深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| class instance { public: int age; int* height; instance(int a,int h) { age = a; cout << a << endl; height=new int(h); cout << *height << endl; } ~instance() { if (height != NULL) { delete height; height = NULL; cout << "已清空" << endl; } } instance(const instance& p) { age = p.age; //height = p.height;编译器默认实现的就是这行代码 //深拷贝如下 height = new int(*p.height); } };
//浅拷贝使两个height指向同一内存地址,会导致将已释放的内存再次释放,引发双重释放安全问题 void test01() { instance p1(18,160); instance p2(p1); cout << p2.age <<*p2.height<<endl; } int main() { test01(); system("pause"); }
|
重载赋值运算符
众所周知,运算符重载后使运算符能实现原本无法完成的工作
赋值运算符,这里我们实现类对类的赋值.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| class MyClass { private: char* data;
public: // 默认构造函数 MyClass(const char* str = "") { data = new char[strlen(str) + 1]; strcpy(data, str); }
// 拷贝构造函数 MyClass(const MyClass& other) { data = new char[strlen(other.data) + 1]; strcpy(data, other.data); }
// 重载赋值运算符 MyClass& operator=(const MyClass& other) { if (this == &other) { return *this; // 处理自赋值情况 }
// 先释放原有资源 delete[] data;
// 分配新内存并拷贝数据 data = new char[strlen(other.data) + 1]; strcpy(data, other.data);
return *this; }
// 析构函数 ~MyClass() { delete[] data; }
// 打印数据 void print() const { std::cout << data << std::endl; } };
int main() { MyClass a("Hello"); MyClass b("World");
std::cout << "Before assignment:" << std::endl; a.print(); // 输出 "Hello" b.print(); // 输出 "World"
a = b; // 使用重载的赋值运算符
std::cout << "After assignment:" << std::endl; a.print(); // 输出 "World" b.print(); // 输出 "World"
return 0; }
|
注意:一定要将被赋值对象中在堆中的数据释放掉.
否则会导致旧资源直接被新资源赋值后,内存覆盖掉
有内存泄露,资源浪费的风险,以及未定义行为的风险
具体会不会发生所谓的双重释放,个人认为不会