注意:默认的拷贝是浅拷贝
浅拷贝(只是机械的拷贝)
public:
CopyConstructor()
{
p = new int(100);
}
/*析构函数*/
~CopyConstructor()
{
assert(p != NULL);
delete p;
}
private:
int *p;
int width;
int height;
};
int main()
{
{
CopyConstructor CopyConstructor1;
CopyConstructor CopyConstructor2(CopyConstructor1);
}/*这里加括号的原因是为了上面两条语句的执行范围只是在代码快中,在这个代码块结束时就要释放两个对象,才能调用其析构函数,否则没有
括号时,上面两句的创建的对象存在范围为整个main函数,只有当整个main函数执行结束才能调用析构函数,也就看不到问题所在,同时也就无法释放分配的内存*/
system("pause");
return 0;
}
分析:
由于在执行
CopyConstructor CopyConstructor1;时
默认构造函数中为指针*p分配内存空间,然后在执行
CopyConstructor CopyConstructor2(CopyConstructor1);时会调用编译器创建的拷贝构造函数,在该拷贝构造函数中,会产生一个临时变量CopyConstructor2.p来接收CopyConstructor1.p指向的地址空间(这里只是机械的拷贝),所以此时就会有两个指针变量指向堆中的同一片内存,当释放两个对象是,就会执行两次析构函数,既
释放两次同一片内存,所以会出错。解决这个问题就需用到深度拷贝
深度拷贝:(适用于堆分配内存的情况)
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;
class CopyConstructor
{
public:
CopyConstructor(const char* str)
{
m_len = strlen(str);
m_p = (char*)malloc(m_len + 1);
strcpy(m_p,str);
}
/*实现深度拷贝其实就是自定以拷贝函数,然后在拷贝函数中重新申请一片内存,此时拷贝就不会出现一片内存有两个指针同时指向的问题*/
CopyConstructor(const CopyConstructor &oop1)
{
m_len = oop1.m_len;
m_p = (char*)malloc(m_len + 1);
strcpy(m_p, oop1.m_p);
}
~CopyConstructor(void)
{
if (m_p!=NULL)
free (m_p);
}
void print()
{
cout << m_p << endl;
}
private:
int m_len;
char* m_p;
};
void maindis(void)
{
CopyConstructor opp2("nihao!");
CopyConstructor opp3(opp2);
opp3.print();
}
int main()
{
maindis();
system("pause");
return 0;
}