C++ 核心 4.2 对象的初始化和清理
4.2 对象的初始化和清理
4.2.1 构造函数和析构函数
对象的初始化非常重要,如果没有初始化,则对象状态是不确定的。 对象的清理也很重要。
构造函数用于对象初始化,析构函数用于对象清理。编译器自动调用,如果不自定义,编译器会实现一个空的函数。
构造函数:成员属性初始化赋值。 析构函数:对象销毁前自动调用。
构造函数语法:类名(){}
无返回值;
函数名称和类名相同;
可以有参数,因此可以重载;
创建对象时自动调用。
析构函数:~类名(){}
无返回值;
函数名称和类名相同,前面加~
;
无参数;
销毁对象前自动调用。
例:
class Person
{
public:
Person(){
cout<<"Person构造函数"<
4.2.2 构造函数的分类及调用
按参数分类:有参和无参 按类型分类:普通构造和拷贝构造
拷贝构造就是从另一个对象复制一份,所以拷贝构造的参数是一个对象。
调用构造函数方法: 括号法
class Person
{
public:
Person(){
cout<<"Person构造函数Person()"<
注意事项:
调用默认构造函数用Person p1;
,不能Person p1();
因为,Person p1();
会被当成函数声明。
回顾:函数声明语法return_type funcname(arg_list);
4.2.3 拷贝构造函数的使用
1.使用已有对象初始化一个新的对象 2.值传递方式作为函数参数 3.值方式返回局部对象
e: 2.值传递方式作为函数参数
void doWork(Peron p){
}
void test02(){
Person p;
doWork(p);
}
3.值方式返回局部对象
Person doWork2(){
Person p1;
return p1;
}
void test03(){
Person p = doWork2();
}
4.2.4 构造函数调用规则
C++默认给一个类添加3个函数: 默认构造、默认析构、默认拷贝(属性值拷贝)
如果你自定义了构造函数,编译器就不会再类添加默认构造函数了,但还会提供默认拷贝。
如果自定义了拷贝,则不会提供默认拷贝,且不提供默认构造。
4.2.5 深拷贝与浅拷贝
浅拷贝:简单的赋值拷贝 深拷贝:在堆区申请空间,赋值
浅拷贝的问题:如果变量是指针类型,浅拷贝直接复制内存地址,在析构函数中,会带来重复释放同一块内存的问题。
总结: 如果属性有在堆区开辟的,要自己实现拷贝构造函数,实现深拷贝。
class Person{
public:
Person(int age, int height){
m_age = age;
m_height = new int(height);//堆区
}
Person(const Person & p){
m_age = p.m_age;
m_height = new int(*p.m_height);
}
~Person(){
if (m_height != NULL){
delete m_height;
m_height = NULL;
}
}
int m_age;
int* m_height;
}
4.2.6 初始化列表
快捷初始化类的属性
语法:
构造函数(): 属性1(值1), 属性2(值2)...{}
class Person{
public:
Person(int a, int b):m_a(a), m_b(b){
}
int m_a;
int m_b;
};
4.2.7 类对象作为类成员
嵌套。
构造时,先构造成员,再构造自己。 析构时,先析构自己,在析构成员。
4.2.8 静态成员
static成员:
- 静态成员变量:
-
- 所有对象共享
-
- 编译阶段分配内存
-
- 类内声明,类外初始化
- 静态成员函数:
-
- 所有对象共享
-
- 只能访问静态成员
class Person
{
public:
static int m_A;// 类内声明
static void func(){
cout<<"static void func()"<
注意:静态变量也是有访问权限的。