浅拷贝
// 浅拷贝: class String { public: String(const char *str) : _str(new char[strlen(str) + 1]) { strcpy(_str, str); } String(const String &s) : _str(s._str) { // 浅拷贝的方式就是将类中的指针指向新的指针 // 这样就是实现了两个执政指向同一空间 // 缺点1:通过类1修改空间内容,类2的内容也回改变 // 缺点2:如果通过类1释放该空间过后,再通过类2释放空间就会出错 } String &operator=(const String &s) { if (this != &s) { _str = s._str; } //返回引用是为了连续的赋值 return *this; } ~String() { cout << "String析构" << endl; // 释放申请来的空间 if (_str) { delete[] _str; } // 防止野指针的出现 _str = NULL; } char *_str_get() { return this->_str; } void _str_set(const char *s) { strcpy(_str, s); } private: char *_str; };
浅拷贝的方式就是将类中的指针指向新的指针
这样就是实现了两个执政指向同一空间
问题1:通过类1修改空间内容,类2的内容也回改变
问题2:如果通过类1释放该空间过后,再通过类2释放空间就会出错
深拷贝的写法
// 深拷贝: class MyString { public: MyString(const char *s) : _str(new char[strlen(s) + 1]) { strcpy(_str, s); } MyString(const MyString &s) : _str(NULL) { MyString temp(s._str); swap(_str, temp._str); } MyString &operator=(const MyString &s) { // 深拷贝的方式就是通过重新构造一个局部类temp获取新的指针 // 然后通过swap交换两个类的指针,相当于使_str重新指向一个新开辟的空间 // 因为是局部类,执行完函数过后相应的就会被释放掉 if (this != &s) { MyString temp(s._str); swap(_str, temp._str); } //返回引用是为了连续的赋值 return *this; } ~MyString() { cout << "MyString析构" << endl; if (_str) { delete[] _str; } _str = NULL; } char *_str_get() { return this->_str; } void _str_set(const char *s) { strcpy(_str, s); } private: char *_str; };
深拷贝的方式就是通过重新构造一个局部类temp获取新的指针
然后通过swap交换两个类的指针,相当于使_str重新指向一个新开辟的空间
因为是局部类,执行完函数过后相应的就会被释放掉
完整程序
#include <iostream> #include <string.h> using namespace std; // 浅拷贝: class String { public: String(const char *str) : _str(new char[strlen(str) + 1]) { strcpy(_str, str); } String(const String &s) : _str(s._str) { // 浅拷贝的方式就是将类中的指针指向新的指针 // 这样就是实现了两个执政指向同一空间 // 缺点1:通过类1修改空间内容,类2的内容也回改变 // 缺点2:如果通过类1释放该空间过后,再通过类2释放空间就会出错 } String &operator=(const String &s) { if (this != &s) { _str = s._str; } //返回引用是为了连续的赋值 return *this; } ~String() { cout << "String析构" << endl; // 释放申请来的空间 if (_str) { delete[] _str; } // 防止野指针的出现 _str = NULL; } char *_str_get() { return this->_str; } void _str_set(const char *s) { strcpy(_str, s); } private: char *_str; }; // 深拷贝: class MyString { public: MyString(const char *s) : _str(new char[strlen(s) + 1]) { strcpy(_str, s); } MyString(const MyString &s) : _str(NULL) { MyString temp(s._str); swap(_str, temp._str); } MyString &operator=(const MyString &s) { // 深拷贝的方式就是通过重新构造一个局部类temp获取新的指针 // 然后通过swap交换两个类的指针,相当于使_str重新指向一个新开辟的空间 // 因为是局部类,执行完函数过后相应的就会被释放掉 if (this != &s) { MyString temp(s._str); swap(_str, temp._str); } //返回引用是为了连续的赋值 return *this; } ~MyString() { cout << "MyString析构" << endl; if (_str) { delete[] _str; } _str = NULL; } char *_str_get() { return this->_str; } void _str_set(const char *s) { strcpy(_str, s); } private: char *_str; }; int main(int argc, char **argv) { // 浅拷贝 String x_str("hello"); String y_str(x_str); char *per = x_str._str_get(); cout << "x_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl; per = y_str._str_get(); cout << "y_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl; cout << "x_str:" << x_str._str_get() << endl; cout << "y_str:" << y_str._str_get() << endl; y_str._str_set("aaa"); cout << "x_str:" << x_str._str_get() << endl; cout << "y_str:" << y_str._str_get() << endl; // 深拷贝 MyString m_str("world"); MyString n_str(m_str); per = m_str._str_get(); cout << "m_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl; per = n_str._str_get(); cout << "n_str中成员指向的空间地址:" << static_cast<const void *>(per) << endl; cout << "m_str:" << m_str._str_get() << endl; cout << "n_str:" << n_str._str_get() << endl; m_str._str_set("bbb"); cout << "m_str:" << m_str._str_get() << endl; cout << "n_str:" << n_str._str_get() << endl; // 两个指针指向不同的空间 return 0; }
运行结果