构造函数 初始化
析构函数 清理
如果你不提供 编译器会提供 但是是空实现

[] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<bits/stdc++.h>

using namespace std;

class Person
{
public:
//1.构造函数没有返回值 不用写void
//函数名与类名相同
//构造函数可以有参数 可以发生重载
//创建对象的时候 构造函数 而且只调用一次
Person()
{
//如果你不自己写 就是空的
cout<<"Person构造函数的调用"<<endl;
}
//2.析构函数 进行清理的操作
//没有返回值 不写void
//函数名与类名相同 区别是在其之前加 ~
//不可以有参数 不能重载
//对象在销毁前自动调用一次
~Person()
{
cout<<"Person析构函数的调用";
}
};

void test01()
{
Person p;//在栈上 调用结束后就释放了 会调用析构函数
}
int main()
{
test01();
return 0;
}

[] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<bits/stdc++.h>

using namespace std;

class Person
{
public:
//构造函数的分类以及调用
//分类
//1.按照参数 无参构造(默认构造)和有参构造
//2. 普通构造 和 拷贝构造
Person()
{

cout<<"Person无参构造函数的调用"<<endl;
}

Person(int a)
{
age=a;
cout<<"Person有参构造函数的调用"<<endl;
}
//拷贝构造函数 要加const 要引用
Person(const Person &p)
{
//拷贝传入的人的身上的所有属性
age=p.age;
}
//2.析构函数
~Person()
{
cout<<"Person析构函数的调用";
}
int age;
};
//调用
void test01()
{
//1.括号法 首要用这个
Person p; //默认构造函数的调用
Person p2(10);//有参构造函数的调用
Person p3(p2); //拷贝构造函数
//注意:调用默认构造不要加小括号 会被认为是函数 声明

//显示法
Person p4=Person(10);//调用有参构造
Person p5=Person(p2);
//注意:不要利用拷贝构造函数 初始化匿名对象 会被认为是对象声明
Person(10); //匿名对象 当前行执行完就无了

//隐式转换法
Person p6=10; //Person p6=Person(10)
Person p7=p5;//相当于构造
}
int main()
{
test01();
return 0;
}

拷贝构造函数的调用时机

[] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include<bits/stdc++.h>
using namespace std;

//拷贝构造函数调用时期
class Person
{
public:
Person()
{
cout<<"Person默认构造函数的调用"<<endl;
}

~Person()
{
cout<<"Person析构函数的调用"<<endl;
}

Person(int age)
{
m_Age=age;
cout<<"Person有参构造函数的调用"<<endl;
}

Person(const Person &p)
{
m_Age=p.m_Age;
cout<<"Person拷贝构造函数的调用"<<endl;
}
int m_Age;
};
//拷贝构造函数调用时期
//1.使用一个已经创建完毕的对象来初始化一个新对象
void test01()
{
Person p1(20);
Person p2(p1);
cout<<"p2的年龄为"<<p2.m_Age<<endl;
}
//2.值传递的方式给函数参数传值
void doWork(Person p)//值传递会启用拷贝函数 这个函数里面的改变不改变原p
{

}

void test02()
{
Person p;
doWork(p);
}
//3.值方式返回局部对象
Person doWork2()
{
Person p1;
cout<<(int*)&p1<<endl;
return p1;
}

void test03()
{
Person p=doWork2();
cout<<(int*)&p<<endl; //p1和p2不是同一个对象 但是devc++优化了 是一样的
//先创建了p1 启用了拷贝构造函数 有了p2 然后p1释放了 最后p2也释放了

}
int main()
{
//test01();
//test02();
test03();
return 0;
}


默认情况下c++编译器至少给一个类添加三个函数
1.默认构造函数(无参 函数体为空)
2.默认析构函数(无参 函数体为空)
3.默认拷贝构造函数 对属性进行值拷贝

构造函数调用规则如下
1.如果定义了有参构造函数 不会提供默认无参构造函数 但是会提供默认拷贝构造函数(值拷贝)
2.如果定义了拷贝构造函数 不会再提供其它构造函数