C++中,拷贝构造指对象的创建是通过拷贝一个已存在的对象来构造一个新的对象问题。在具体的应用过程中,拷贝构造的实际应用场景非常普遍。本文将对拷贝构造过程中的深拷贝和浅拷贝进行深入剖析。
示例如下:
// XdnString类成员及成员函数原型
class XdnString{
public:
XdnString( const char *str = NULL ); // 构造函数
~XdnString( ); // 析构函数
XdnString( const XdnString &other ); // 拷贝构造函数
private:
char *m_data;
};
浅拷贝实现:
XdnString::XdnString( const char *str )
{
m_data = str;
}
XdnString::~XdnString()
{
}
XdnString::XdnString( const XdnString &other )
{
this->m_data = other.m_data;
}
int main()
{
char crr[] = {“hello xuedaon”};
XdnString str( crr ); // 此时str对象中的m_data指针指向crr首地址
XdnString ctr = str; // 此时ctr对象中的m_data指针指向crr首地址
}
通过上述代码的实现,发现此时str、ctr两个对象的m_data指针都指向crr数组的首地址。使得三个对象都可以去修改同一段内存。这种写法一般称为浅拷贝(或者位拷贝)。
而深拷贝主要是杜绝上述问题的出现。深拷贝除了处理对象内存拷贝问题,还解决对象内存中指向外部内存的拷贝问题。以上述例子实现如下:
XdnString::XdnString( const char *str )
{
if( str == NULL ){
m_data = new char [1];
m_data[0] = ‘ ’;
}else{
m_data = new char[strlen( str ) + 1];
strcpy( m_data, str );
}
}
XdnString::~XdnString()
{
delete []m_data;
m_data = NULL;
}
XdnString::XdnString( const XdnString &other )
{
this->m_data = new char[ strlen( other.m_data +1 ) ];
strcpy( this->m_data, other.m_data );
}
int main()
{
char crr[] = {“hello xuedaon”};
// 此时str对象中的m_data指针指向自己分配的内存,并把数组内存拷贝进去
XdnString str( crr );
// 此时ctr对象中的m_data指针指向自己分配的内存,并把str中m_data指针指向的内存拷贝进去
XdnString ctr = str;
}
通过上述代码的实现,发现此时str、ctr两个对象的m_data指针都指向自己独有的内存。使得三个对象的内存各独立。这种写法一般称为深拷贝。
通过上述例子可以很清楚认识到当类的成员有指针类型时,应当考虑或者高度怀疑是否需要使用深拷贝对它的拷贝构造进行重新实现(类的默认拷贝构造为浅拷贝)。