长春网站设计山东一建建设有限公司官方网站
web/
2025/9/28 9:30:04/
文章来源:
长春网站设计,山东一建建设有限公司官方网站,h5响应式网站源码下载,网站图片如何做链接文章目录 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符和封装4.1访问限定符4.2封装 5.类的作用域6.类的实例化6.2结构体内存对齐规则 7.this指针7.2this指针的特性 封装#xff08;补充#xff09; 1.面向过程和面向对象初步认识
C面向对象但不纯面向… 文章目录 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符和封装4.1访问限定符4.2封装 5.类的作用域6.类的实例化6.2结构体内存对齐规则 7.this指针7.2this指针的特性 封装补充 1.面向过程和面向对象初步认识
C面向对象但不纯面向对象。JAVA纯面向对象。 所以C支持C和C面向对象混编。 C面向过程关注的是过程
2.类的引入
类和结构体的区别
类里可以有数据成员变量类可以定义函数可以写成ListNode,不需加struct。 C struct ListNode是类型。 C
//C兼容C结构体的用法。
typedef struct ListNode
{int val;struct ListNode* next;
}LTN;C
//C把结构体升级成类
struct ListNode//声明这是个类struct关键字不能去掉
{int val;ListNode* next;//后面想用这个类型的时候可以去掉。
};如何用类 C数据和方法分离C方法可以在类的里面
struct Stack
{
//成员函数
//成员函数直接定义到类里面void Init(int n4)//缺省值{a (int*)malloc(sizeof(int) * n);if (nullptr a){perror(malloc申请空间失败);return;}capacity n;size 0;}void Push(int x){//...a[size] x;}//成员变量int* a;int size;int capacity;
};
int main()
{Stack st;//对象//如何调用函数st.Init(4);st.Push(1);st.Push(2);st.Push(3);st.Push(4);return 0;
}C可以用struct定义类但更喜欢用class定义类。
3.类的定义
class className
{//类体包括成员函数类的方法和成员变量类的属性
}//一定要注意后面的分号class定义类的关键字className类名{}类的主体类体中的内容类的成员 定义一个声明和定义分离的类。 缺省参数生命和定义不能同时给一般在声明给。 Stack.h
#pragma once
#include string.h
#include stdlib.h
//类成员函数声明和定义分离
struct Stack
{//成员函数void Init(int n 4);//缺省参数在声明给void Push(int x);//类的声明//成员变量int* a;int size;int capacity;
};Stack.cpp
#include Stack.h
void Stack::Init(int n)//Stack告诉编译器Init不是全局函数是栈这个类的成员函数
{a (int*)malloc(sizeof(int) * n);//看栈这个类里有没有a这个成员变量if (nullptr a){perror(malloc申请空间失败);return;}capacity n;size 0;
}
void Stack::Push(int x)
{//...a[size] x;
}用class Stack却编不过为什么呢 此时要用到访问限定符。
4.类的访问限定符和封装
4.1访问限定符
C访问限定符有三种公有保护和私有现阶段保护和私有没有区别。共有及在类外可以直接访问。保护和私有在类里可以访问类外不可访问。
公有保护私有publicprotectprivate
访问限定符不会限定在类里面的访问锁外面的人不锁里面的人。类里面可以有多个访问限定符限定从该访问限定符到下一个访问限定符出现时位置如果没有下一个访问限定符则到}结束。class的默认访问限定符是私有struct是公有因为struct要兼容C。所以上一文中报错了。 实际生活中不希望默认希望大家指清楚到底是私有还是公有。 注意访问限定符只在编译时有用当数据映射到内存后没有任何访问限定符上的区别。
#pragma once
#include string.h
#include stdlib.h
struct Stack
{
publicvoid Init(int n 4);void Push(int x);
privateint* a;int size;int capacity;
};大多数情况下成员变量都是私有的成员函数不给别人用的是私有给别人用的是公有。 C中struct和class没有区别但是struct可以像C语言去用。 Test.cpp
class Date
{
public:void Init(int year, int month, int day){_year year;_month month;_day day;}
private:int _year;int _month;int _day;};
int main()
{Stack st;Date d1;d1.Init(2023, 2, 3);//调用函数年月日被初始化return 0;
}4.2封装
【面试题】面向对象的三大特性封装继承多态 封装将下面的细节藏起来本质是一种更好的管理。 C的封装将数据和方法都放在类里面去了即当前封装的极限并把自己想访问的定义成共有不想的定义成私有和保护。
5.类的作用域
类定义出一个新的作用域类域。
class Person
{public:void PrintPersonInfo();private:char _name[20];char _gender[3];int _age;
};
void Person::PrintPersonInfo()//PrintPersonInfo属于Person这个类域
{cout_name _gender _ageendl;//此时可以调用私有
}6.类的实例化
即用类类型 声明即要定义这个函数或变量这个变量的类型是什么名称是什么参数是什么但实际这个变量没有出来。定义即把其实实在在在的空间给开出来对于变量而言。 类就像一个别墅的设计图设计了细节但不能住人实例化即根据设计图建造出一栋栋别墅。
class Date
{
public:void Init(int year, int month, int day){_year year;_month month;_day day;}//函数的定义
private:int _year;int _month;int _day;//声明没有开空间};只需要计算成员变量的大小。
int main()
{//类对象实例化--开空间Date d1;//定义才是开空间对于对象整体定义。//Date._year1;//Date::year0;//以上两种不可以声明内不可存数据。//d1._year1;//也不行访问限定符是私有的。访问不了访问的时候需要调用这个函数。改成公有就可以了。d1.Init(2023,9,12);//Init函数存在哪里呢d1._year;coutsizeof(d1)endl;//类对象大小要考虑内存对齐规则return 0;
}//输出12为什么成员变量存在对象里面成员函数不存在对象里面 每个对象的成员变量不一样需要独立存储。 每个对象调用的成员函数一样放到共享公共区域代码段。 只需要计算成员变量的大小。
//类中既有成员变量又有成员函数
class A1{
pubic:void f1(){}
private:int a;
};//sizeof(A1):4
//类中仅有成员函数
class A2{
public:void f2(){}
};//sizeof(A2):1//【考点】如果是0A2 aa1没有实例化不能取地址
//类中什么也没有
class A3
{}//sizeof(A3):1这一个字节用来进行占位不存储有效数据标识对象存在过被实例化定义出来了。没有成员变量的类都是一个字节
6.2结构体内存对齐规则
第一个成员在于结构体偏移量为0的地址处其他成员变量要对齐到某个数字对其书的整倍的地址处 注意对齐数编译器默认的一个对齐数与该成员大小的较小值。VS默认对齐数为8.结构体的总大小最大对齐数所有变量类型最大者与默认对齐参数取最小的整数倍。如果嵌套了结构体的情况嵌套的结构体对齐到自己的最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体的对齐数的整数倍。
7.this指针
原来代码
class Date
{
public:void Init(int year, int month, int day){_year year;_month month;_day day;}编译器处理完
class Date
{
public:void Init(Date*this,int year, int month, int day){this-_year year;this-_month month;this-_day day;}原来代码
int main()
{Date d1;Date d2d1.Init(2023, 2, 3);d2.Init(2022, 2, 3);return 0;
}编译器处理完
int main()
{Date d1;Date d2d1.Init(d1,2023, 2, 3);d2.Init(d2,2022, 2, 3);return 0;
}如果是d1调用this是d1的地址赋值给d1的年月日。 不可以自己去加。
//可以在类里使用this但是实参和形参里不可以
coutthisendl;
this-_year year;
this-_month month;
this-_day day;
//一般不会这么写this存在哪里–存在对象里面答案❌。 在栈上因为他是形参隐含的形参不需要显示写是编译器自己加的。/VS下通过ecx寄存器。 程序进行编译编译后成员变量存在对象里实例化出一个对象对象存在栈上。成员函数不要存在栈中因为成员函数存在一个公共区域编译的时候要确定call这个函数的地址这个地址不在对象中去找在代码段。因为函数的地址是这些指令的地址这些指令是存在哪呢存在于代码段。两个东西完全不一样要从两个不同的角度理解。一个是指令一个是指令运行过程中的相关数据。不要把两个东西混在一起。 《深入理解计算机系统》——修炼内功
7.2this指针的特性
void func()
{coutthisendl;coufunc()endl;}
int main()
{
//编译报错 运行崩溃 正常运行Date* ptrnullptr;ptr-func();//结果正常运行ptr-Init(2023,9,12);//运行崩溃用this去解引用了this-yearptr-_year;//会崩溃因为_year在对象里面,到指针指向的对象去找指针是一个空指针相当于解引用。*ptr).func();//正常运行ptr真正的意义是传递给this所以也是正常运行没有解引用这个行为Date::func();//不能这么调用因为要传递this指针。没有this指针调用。
}指针调用用箭头有箭头不一定解引用。函数不在对象里。调用这个函数要call这个地址这个地址在公共区域去找公共区域代码段。 成员函数不可以不用对象去调直接func。
受到类域的限制一般都不在类域里面去找只在全局去找。在全局找func找不到告诉func是Date的成员函数调用成员函数要传递this指针所以没有解引用但是ptr传递给了this指针(coutthisendl;)所以this指针是一个空但不会报错只有发生了恶劣的行为才会报错。会不会解引用取决于要不要在对象中去找而不是有没有这个符号。 调用函数一共就需要两个动作一个是传参传this指针一个是调用函数这两个动作都不涉及要去解引用。 成员函数不是成员对象。
封装补充
C语言和C真正的区别数据结构的实现与语言无关
CC数据和方法分离的都封装在类里面名字繁琐简洁数据访问自由不受限制控制访问方式。愿意给你访问的公有不愿意私有底层一样
封装在一起才能通过访问限定符限制。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/83259.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!