构造函数的分类及调用
两种分类方式:
按参数分为:有参构造和无参构造
按类型分为:普通构造和拷贝构造
三种调用方式:括号法、显示法、隐式转换法
注意:
1.调用默认构造函数的时候,不要加()
2.不要利用拷贝构造函数初始化匿名对象,编译器会认为是对象的声明
匿名对象的特点:当前行执行结束后,系统会立即回收掉匿名对象。
C++中拷贝构造函数调用时机通常有三种情况:
1.使用一个已经创建完毕的对象来初始化一个新对象。
2.值传递的方式给函数参数传值。
3.以值方式返回局部对象。
默认情况下,c++编译器至少给一个类添加3个函数
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝构造函数,对属性进行值拷贝
构造函数调用规则:
1.如果用户定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造
2.如果用户定义拷贝构造函数,C++不再提供其他构造函数
深浅拷贝是面试经典问题,也是常见的一个坑。
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
C++提供了初始化列表语法,用来初始化属性
语法:构造函数( ):属性1(值1),属性2(值2)……{}
类对象作为类成员。
C++类中的成员可以是另一个类的对象,称该成员为对象成员
例如
class A{}
class B{
A a;
}
B类中有对象A作为成员,A为对象成员。
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
静态成员分为
静态成员变量:所有对象共享同一份数据,在编译阶段分配内存,类内声明,类外初始化
静态成员函数:所有对象共享同一个函数,静态成员函数只能访问静态成员变量
在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上。
每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。
问题:这一块代码是如何区分哪个对象调用自己的呢?
C++通过提供特殊的对象指针,this指针解决此问题。this指针指向被调用的成员函数所属的对象
this指针是隐含每一个非静态成员函数内的一种指针
this指针不需要定义,直接使用即可
this指针的用途:
1.当形参和成员变量同名时,可用this指针来区分
2.在类的非静态成员函数中返回对象本身,可使用return *this
c++中空指针也是可以调用成员函数的,但要注意有没有用到this指针,
如果用到this指针,需要加以判断保证代码的健壮性。
const修饰成员函数
常函数:
1.成员函数后加const,称这个函数为常函数
2.常函数内不可以修改成员属性
3.成员属性声明时加关键字mutable后,在常函数中依然可以修改
常对象:
1.声明对象前加const,称该对象为常对象
2.常对象只能调用常函数
友元的目的就是让一个函数或者类访问另一个类中私有成员。
友元的关键字为 friend
友元的三种实现:
1.全局函数做友元
2.类做友元
3.成员函数做友元
运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
加号运算符重载:实现两个自定义数据类型相加的运算
左移运算符重载:可以输出自定义数据类型
递增运算符重载:实现自己的整型数据
关系运算符重载:可以让两个自定义类型对象进行对比操作。
函数调用运算符重载:由于重载后使用的方式非常像函数的调用,因此称为仿函数。仿函数没有固定写法。
赋值运算符重载:
C++编译器至少给一个类添加4个函数
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝构造函数,对属性进行值拷贝
4.赋值运算符 operator=,对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题。