默认情况下,创建一个类时编译器自动给一个类添加三个函数
- 默认构造函数
- 默认析构函数
- 默认拷贝构造函数,对属性进行拷贝
- 如果定义了有参构造函数,那么编译器不再提供默认构造函数,但是会提供默认拷贝构造函数
- 如果定义了拷贝构造函数,编译器不再提供任何构造函数
class Person {
string m_name;
int m_age;
public:
Person(int age) {
m_age = age;
cout << "这是Person的有参构造函数" << endl;
}
};
class Student {
string m_name;
int m_id;
public:
Student(const Student & s) {
m_id = s.m_id;
cout << "这是Student的拷贝构造函数" << endl;
}
};
int main(){
Person p;//false 定义有参构造函数时,编译器不再提供默认构造函数
Person p1(p);//true 仍提供拷贝构造函数
Student s;//false
Student s1(s);//仅拷贝对象s的m_id属性到s1;
return 0;
}
二. 拷贝构造函数的调用时机
两种情况会调用拷贝构造函数
- 使用拷贝构造函数初始化一个新的对象
- 用值传递的方式传给函数或以值方式返回局部对象(传递参数时自动拷贝创建匿名对象)
class Person {
string m_name;
int m_age;
public:
Person(int age) {
m_age = age;
}
Person(const Person & p) {
m_age = p.m_age;
cout << "调用了Person的拷贝构造函数" << endl;
}
};
void test01(Person p) {
cout << "调用test01函数,值传递" << endl;
}
Person test02(const Person & p) {
cout << "调用test02函数,值返回" << endl;
return p;
}
int main() {
//拷贝构造函数初始化新的对象
Person p(18);
Person p1(p);
//用值传递的方式传给函数
test01(p);
//以值方式返回局部对象
test02(p);
return 0;
}
输出结果如图
总结:只要对对象进行拷贝,就会调用拷贝构造函数。
浅拷贝:直接赋值拷贝,包括指针
深拷贝:在堆区重新申请空间并且使新指针指向新的空间
当把一个对象中的指针赋给另一个对象时,实际上只复制了该指针在栈中的值而不是对应在堆中的数据。因此两个对象中指针指向同一块内存,无论哪个对象对该指针进行操作,都会影响到另一个对象中相应的指针。因此,两个对象是联动的。
浅拷贝:class Person {
string m_name;
int * m_age;
public:
Person(string name, int age) {
m_name = name;
m_age = new int(age);
}
void changeInfo(string name, int age) {
m_name = name;
*m_age = age;
}
void showInfo() {
cout << m_name << "今年" << *m_age << "岁" << endl;
}
};
int main() {
Person p1("老张三",54);
Person p2(p1);//拷贝了指针m_age, 与老张三p1中指针指向相同地址
p2.changeInfo("小张三", 24);
p1.showInfo();
p2.showInfo();
return 0;
}
输出结果如图
class Person {
string m_name;
int * m_age;
public:
Person(string name, int age) {
m_name = name;
m_age = new int(age);
}
Person(const Person& p) {
//创建拷贝构造函数使指针指向新的空间
m_age = new int(*p.m_age);
}
//使用new后在析构函数中使用delete对内存进行释放
~Person() {
if (m_age != NULL){
delete m_age;
}
void changeInfo(string name, int age) {
m_name = name;
*m_age = age;
}
void showInfo() {
cout << m_name << "今年" << *m_age << "岁" << endl;
}
};
int main() {
Person p1("老张三",54);
Person p2(p1);
p2.changeInfo("小张三", 24);
p1.showInfo();
p2.showInfo();
return 0;
}
输出结果如图


![[C++学习第n+1天]构造函数调用规则 拷贝构造函数调用时机 深拷贝与浅拷贝 [C++学习第n+1天]构造函数调用规则 拷贝构造函数调用时机 深拷贝与浅拷贝](http://www.mshxw.com/aiimages/31/1011271.png)
