一般来说拷贝构造函数会将前者属性值进行值拷贝一份,比如p2(p1),p1中的属性就被复制一份给p2,这里的复制就是,比如p1中有age(年龄属性)复制一份给p2,此时p1.age和p2.age的值相同,但是但是但是地址是不同的,不同的不同的,而且这一切都是发生在栈区的复制,(栈区是被编译器自动回收的),p1析构完,p2析构,一切都相安无事。
#include<iostream>
#include<string>
using namespace std;
class Dog
{
public:
int age;
int* weigth;
Dog(int a, int w)
{
age = a;
weigth = new int(w);
cout << "有参构造函数" << endl;
}
/*Dog(const Dog &d)
{
age = d.age;
weigth = new int(*d.weigth);
cout << "拷贝构造函数" << endl;
}*/
~Dog()
{
if (weigth != NULL)
{
delete weigth;
}
cout << "析构函数" << endl;
}
};
void test()
{
Dog dog1(2, 10);
Dog dog2(dog1);
}
int main()
{
test();
return 0;
}
问题就出现在堆区,如果你再构造一个属性*weigth(体重),这个属性在类内用一个指针变量来接收他,拷贝构造函数会将前者属性值的地址进行值拷贝一份,一定是地址啊,而且这两个地址是放在栈区的,但是但是这两个地址指向同一块堆区内存,在析构完p2的时候,也就是说weigth(地址变量)删除了,堆区上的数据释放了,那么在析构p1的weigth时,堆区并没有数据了,应该释放什么呢?
#include<iostream>
#include<string>
using namespace std;
class Dog
{
public:
int age;
int* weigth;
Dog(int a, int w)
{
age = a;
weigth = new int(w);
cout << "有参构造函数" << endl;
}
Dog(const Dog &d)
{
age = d.age;
//在堆区上重新开辟一块内存指向栈区的指针,这样的话。weigth就不是相同的地址了
weigth = new int(*d.weigth);
cout << "拷贝构造函数" << endl;
}
~Dog()
{
if (weigth != NULL)
{
delete weigth;
}
cout << "析构函数" << endl;
}
};
void test()
{
Dog dog1(2, 10);
Dog dog2(dog1);
}
int main()
{
test();
return 0;
}
模型部署