1.拷贝构造函数的调用时机
- 使用一个已经创建完的对象来初始化另一个对象
- 值传递的方式给函数参数传参
- 以值的方式返回局部对象
#include <iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person默认构造函数" << endl;
}
Person(int age)
{
m_age = age;
cout << "preoson有参构造函数" << endl;
}
Person(const Person & p)
{
cout<< "person拷贝构造函数" << endl;
m_age = p.m_age;
}
int m_age;
}
void test1()
{
Person p1(20);
Person p2(p1); //使用一个已经创建完的对象来初始化另一个对象
}
void dowork(person p)
{
//值传递会拷贝一个副本出来,所以也会调用拷贝构造函数
}
void test2()
{
Person p;
dowork(p); //值传递
}
void dowork2()
{
Person p1;
return p1; //p1是一个局部对象,用值的方式返回,不会返回p1,会拷贝一个副本返回。
}
void test3()
{
Person p3 = dowork2();
}
int main()
{
test1();
return 0;
}#include <iostream>
using namespace std;
class Person
{
public:
Person()
{
cout << "Person默认构造函数" << endl;
}
Person(int age)
{
m_age = age;
cout << "preoson有参构造函数" << endl;
}
Person(const Person & p)
{
cout<< "person拷贝构造函数" << endl;
m_age = p.m_age;
}
int m_age;
}
void test1()
{
Person p1(20);
Person p2(p1); //使用一个已经创建完的对象来初始化另一个对象
}
void dowork(person p)
{
//值传递会拷贝一个副本出来,所以也会调用拷贝构造函数
}
void test2()
{
Person p;
dowork(p); //值传递
}
void dowork2()
{
Person p1;
return p1; //p1是一个局部对象,用值的方式返回,不会返回p1,会拷贝一个副本返回。
}
void test3()
{
Person p3 = dowork2();
}
int main()
{
test1();
return 0;
}
所以为什么拷贝构造函数要加引用和const
- 引用:如果不加引用,那么拷贝构造函数就是值传递,值传递就会再次调用拷贝构造函数,这样就会永远的递归调用下去
- 如果在函数中不会改变引用类型参数的值,加不加const的效果是一样的。而且不加const,编译器也不会报错。但是为了整个程序的安全,还是加上const,防止对引用类型参数值的意外修改。
2.深拷贝和浅拷贝
- 浅拷贝:简单的赋值拷贝操作
- 深拷贝:在堆区重新申请空间,进行拷贝操作
深拷贝:
Person(const Person & p)
{
m_age = p.m_age;
//m_height = p.m_height; 编译器默认实现
//深拷贝
m_height = new int(*p.m_height);//其实这里的new也就是有参构造函数,参数为p的m_height值
}