文章目录
拷贝构造函数的定义
拷贝构造函数定义如下:
- 拷贝构造函数是构造函数的一个重载形式。
- 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。
使用拷贝构造时势必要牵扯到深浅拷贝问题。那么什么是深浅拷贝呢?
浅拷贝
也称位拷贝,编只是将对象中的值拷贝过来(默认生成的拷贝构造函数即是浅拷贝)
class String
{
public:
String(const char* str = "")
{
if (str == nullptr)
{
assert(false);
return;
}
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
~String()
{
if (_str)
{
delete _str;
_str = nullptr;
}
}
private:
char* _str;
};
int main()
{
String s1("hello world!");
String s2(s1);
return 0;
}
- 这里我们没有显示定义拷贝构造函数,所以使用的是系统默认生成的默认构造函数(浅拷贝)。但是程序运行时会发现在第二次析构时会报错,这是什么情况?
- 这是必然的。s1和s2同时指向了存储字符串的这一片空间。对于对象s1和s2来说程序结束时必须调用俩次析构函数,因此同一片空间释放俩次必然会报错。
- 为了解决浅拷贝带来的问题,引入了深拷贝
深拷贝
String(const String& s)
:_str(new char[strlen(s._str) + 1])
{
strcpy(_str, s._str);
}
- 此时完美地解决了同一片空间释放多次的问题。
传值引起无穷递归问题
假设我们认为以下代码可以正常编译(实际上编译器不会允许这种情况发生,因为拷贝构造传参只允许传引用)
class Test
{
public:
Test(int num = 0)
{
_num = num;
}
Test(const Test t)
{
_num = t._num;
}
private:
int _num;
};
int main()
{
Test t1(123);
Test t2(t1);
return 0;
}