浅拷贝
class Student
{
public:
Student(int weight, int height)
{
m_weight = weight;
m_height = height;
}
Student(const Student& p)
{
m_height = p.m_height;
m_weight = p.m_weight;
cout << "拷贝构造函数的调用" << endl;//此函数即使编译器提供的
//拷贝构造函数,即浅拷贝
}
int m_weight;
int m_height;
~Student()
{
cout << "析构函数的调用" << endl;
}
};
当拷贝遇到在成员变量在堆上开辟时,浅拷贝就会出现一些问题;
例如:(错误示范,和错误分析)
class Student
{
public:
Student(int weight, int height)
{
m_weight = weight;
m_height = new int(height);//在堆上开辟的变量;
}
Student(const Student& p)//和编译器提供的拷贝函数相同
{
m_height = p.m_height;
m_weight = p.m_weight;
cout << "拷贝构造函数的调用" << endl;
}
~Student()
{
if (m_height != NULL)
{
delete m_height;//堆上开辟的空间由程序员手动释放
//析构函数的作用也就出现了;
m_height = NULL;
}
cout << "析构函数的调用" << endl;
}
int m_weight;
int *m_height;
};
void test01()
{
Student p(50,160);
Student p2(p);
//根据栈先进后出,后进先出规则,p2会先被销毁。p2被销毁执行析构函数
//然后p执行析构函数,会导致开辟的空间重复释放;
}
int main()
{
test01();
return 0;
}
解决办法:深层拷贝
class Student
{
public:
Student(int weight, int height)
{
m_weight = weight;
m_height = new int(height);
}
Student(const Student& p)
{
m_height = new int (*p.m_height);
//解决办法是,拷贝时在堆上再次开辟空间,避免p和p2的m_height指向同一地址;
m_weight = p.m_weight;
cout << "拷贝构造函数的调用" << endl;
}
~Student()
{
if (m_height != NULL)
{
delete m_height;
m_height = NULL;
}
cout << "析构函数的调用" << endl;
}
int m_weight;
int *m_height;
};
void test01()
{
Student p(50,160 );
Student p2(p);
cout << *p2.m_height << " " << p2.m_weight << endl;
}
int main()
{
test01();
return 0;
}
同时有一个思考是:p,p2的m_height指向同一个地址;p2m_height指向的地址被释放后,p又怎么会重复释放,不是有if(m_height!=NULL),判断吗?
留个问题,待后续探索;