提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
构造函数的初始化和清理
1.构造函数和析构函数
构造函数
1.没有返回值,不用写void
2.可以有参数,可以发生重载
3.函数名和类名相同
4.创造对象的时候,编译器自动调用构造函数,而且只调用一次
析构函数
1.函数名和类名相同,在名称前面加~
2.没有返回值,不用写void
3.不可以有参数,也不可以发生重载(相区别与构造函数)
4.在对象销毁之前,会调用析构函数,而且只调用一次
总结: 构造函数和析构函数都是必须有的实现,如果我们自己不提供,编译器会自己提供一个空实现的构造和析构。
2.构造函数的分类及调用
无参构造
当我们创建对象的时候,想要调用无参构造函数,对象后面不可以加()
举个例子:
有参构造,支持函数重载
拷贝构造
调用方式(括号法,显示法,隐式转换法)
注意的的点: 不能利用拷贝构造函数来初始化匿名对象,编译器会认为是对象声明, //Person p5(p4)
拷贝构造函数 要加const
我们一般平时用得多的是括号法
3.拷贝构造函数的调用时机
C++拷贝构造函数的调用时机通常有三种情况:
- 使用一个创建完毕的对象来初始化一个新的对象
- 值传递的方式给函数参数传值
- 以值方式来返回局部对象
4.构造函数调用规则
默认情况下,C++编译器会自动给一个类添加三个函数
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝函数(对类里面的属性进行拷贝)
调用规则如下:
1.如果用户定义有参构造函数,那么编译器不会提供无参构造函数,但是会提供拷贝构造函数
2.如果用户自定义拷贝构造函数,那么将无法提供其他构造函数
5.深拷贝和浅拷贝
深拷贝是面试的经典问题,也是常见的一个坑
浅拷贝:简单的赋值操作
深拷贝:在堆区重新new空间,进行拷贝操作
这就是利用深拷贝解决浅拷贝的问题
//构造函数
class Person
{
public:
//无参
Person()
{
cout << "调用无参构造函数" << endl;
}
//有参
Person(int a,int high)
{
cout << "调用有参构造函数" << endl;
m_age = a;
m_high = new int(high);
}
//拷贝构造函数
Person(const Person& p)
{
cout << "调用拷贝构造函数" << endl;
m_age = p.m_age;
//利用深拷贝在堆区重新开辟一个空间,避免内存重复释放
m_high = new int(*p.m_high);
}
//析构
~Person()
{
cout << "调用析构函数" << endl;
if (m_high != NULL)
{
delete m_high;
}
}
public:
int m_age;
int* m_high;
};
int main()
{
Person p1(18, 180);
Person p2(p1);
cout << "年龄:" << p1.m_age << "身高" << *p1.m_high << endl;
cout << "年龄:" << p2.m_age << "身高" << *p2.m_high << endl;
return 0;
}
成功调用两个析构函数,完美解决问题。
总结: 如果属性中有需要用到堆区开辟空间的,自己定义拷贝构造函数,防止浅拷贝带来的问题
6.初始化列表
功能:用来初始化类型属性
语法:构造函数():属性1(值1),属性2(值2),属性3(值3)…{}
7.类对象作为类成员
顾名思义:C++类中的成员可以是另一个类的对象,我们称该成员时对象成员
例如:
在B类中有A类的对象a 那么问题来了,那么当创建B对象时候,A与B的构造和析构的顺序是谁先谁后呢?
代码说话!
class A
{
public:
A()
{
cout << "调用A默认构造函数" << endl;
}
~A()
{
cout << "调用A析构函数" << endl;
}
};
class B
{
public:
B()
{
cout << "调用B默认构造函数" << endl;
}
~B()
{
cout << "调用B析构函数" << endl;
}
public:
A a;
};
int main()
{
B b;
return 0;
}
总结:
当B类中存在A类对象,那么在创建B类对象的时候先执行A类对象的默认构造函数,再执行B类的默认构造函数,结束之后,先执行B类的析构函数,再执行A类析构函数
上图:
8.静态成员
静态成员就是在成员函数或者成员变量前面加上关键字static 静态成员含有的特点:
1.所有对象共享共一份数据
2.在编译截断分配内存
3.类内声明,类外初始化
静态成员变量
静态成员函数
静态成员函数特点:
1.所有对象共享同一个函数
2.静态成员函数只能访问静态成员变量
const修饰成员函数
常函数:
1.成员函数后面加上const后 我们称这个函数是常函数
2.常函数内不可以修改成员属性
3.成员属性声明时候加上关键组mutable之后,在常函数中依然可以修改
常对象
1.声明对象前面加上const,称为常对象
2.常对象只能调用常函数
如有错误,欢迎各位大佬指点!