C++学习:类和对象
类和对象
- 类的构成
- 访问限定符
- 对比struct
- 默认成员函数
- 构造函数
- 析构函数
- 拷贝构造
- 赋值重载
- 类的内存管理
- 创建顺序和析构顺序
- 类的使用
- 内部类
- 仿函数
- 匿名对象
- 静态成员变量和静态成员函数
类的构成
类由成员函数和成员变量组成,也可设置为空类
访问限定符
类域外直接访问
- public
可在类域外直接通过对象.成员的方式访问或类类型指针->成员
不可类域外直接访问
- protected
- private(class默认为private)
不可在类域外直接访问,但是可以通过成员函数得到成员变量的拷贝或修改成员变量的值
继承方式和访问限定符决定派生类是否能在派生类类域直接访问基类成员变量或成员函数
对比struct
C++中struct被定义为类,默认为public
- 内存对齐
和C语言一样,struct和class都会根据空间最大的变量进行内存对齐,提高读取效率
默认成员函数
不显示定义,编译器默认定义
注:成员函数默认第一个参数隐式传入this指针指向自身
构造函数
用于类对象的初始化,不开辟空间创建对象,只用于初始化
- 默认构造
不带参数的构造函数,包括:无参构造,全缺省参数构造,编译器默认生成的构造
- 初始化列表
classDate{date(int year,int month,int day):_year(year),_month(month),_day(day)//最先进行,根据声明顺序进行初始化{}private:int _year=1;//无初始化列表时再根据定义时缺省值int _month=1;int _day=1;};const对象和引用必须在初始化列表初始化,进入函数体相当于赋值进行修改
注:构造函数可重载,无参构造和全缺省参数构造不能同时存在
析构函数
有空间申请的类必须显示定义析构函数释放空间
- new和delete
new底层也是调用malloc,但是会自动调用构造函数进行初始化
delete同理
拷贝构造
特殊的构造函数,由一个已经存在对象初始化另一个对象
由于系统生成的默认拷贝构造都是浅拷贝,通常需要自定义生成深拷贝构造
拷贝构造第一个参数必须是该类对象的引用,其余参数必须有缺省值
C++传值传参都为拷贝构造,如归传入非引用对象会触发拷贝构造,导致无穷递归调用
赋值重载
由一个已经存在对象赋值给另一个也已存在对象
- 运算符重载
重载运算符参数数量和原运算符参数数量相同,一元运算符重载后有一个参数,二元运算符重载后有两个参数,左侧变量作为第一个参数,右侧变量作为第二个参数,作为成员函数时,第一个参数是this指针
.*::sizeof?..//不可重载类的内存管理
创建顺序和析构顺序
先创建后析构,后创建先析构
*多对象构造
Aa1(1,1);Aa2(2,2);Aa3(3,3);A*p1=newA[3]{a1,a2,a3};A*p2=newA[3]{A(1,1),A(2,2),A(3,3)};A*p3=newA[3]{(1,1),(2,2),(3,3)};//三种方式等价类的使用
内部类
友元
友缘可突破类域限制访问类内成员,访问私有成员变量
voidfunction();classA{};classB{friendvoidfunction();friendclassA;//友缘函数和友缘类可访问类内私有成员变量};- 内部类默认为外部类的友缘,且计算空间时内外部独立计算
classA{classB//类B可访问A的私有成员变量{};};仿函数
无成员变量,重载了()运算符实现 对象() 调用功能,达到模拟函数的效果
classfunction(){public:intoperator()(int a,int b){returna+b;}};functionfunc;cout<<func(1.2);//达到类似函数的效果匿名对象
在面对临时使用类成员函数,避免手动创建对象和析构对象时可使用匿名对象
classA{public:A(int x){}voidPrint(){cout<<_s;}private:string _s=abc;}:voidfunc(Aa){}intmain(){//生命周期只在这一行,执行完会自动析构func(A(10));//作为参数可比避免手动创建和析构对象A().Print();//可临时调用成员函数return0;}静态成员变量和静态成员函数
类内声明静态成员变量必须要在类外初始化,该静态成员变量为每一个类对象共享
类内声明静态成员函数由于不属于如何一个类,且无this指针传入,无法访问类内非静态成员变量
classA{public:staticvoidfunc(){};staticint a;};//定义时不需要staticintA::a=10;//访问静态成员变量需要加访问限定符A::func()