###淺拷貝的問題 預設提供的拷貝構造就是淺拷貝,如果拷貝的對象中含有成員指針變數指向堆區中的記憶體空間,那麼就會出現兩個對象中的成員指針變數指向同一塊堆區空間,當方法執行結束後,對象就會被釋放,調用析構函數(析構函數中存在釋放在堆區開闢的記憶體空間),就會存在一塊記憶體空間被多次釋放的問題。 ###解決 ...
淺拷貝的問題
預設提供的拷貝構造就是淺拷貝,如果拷貝的對象中含有成員指針變數指向堆區中的記憶體空間,那麼就會出現兩個對象中的成員指針變數指向同一塊堆區空間,當方法執行結束後,對象就會被釋放,調用析構函數(析構函數中存在釋放在堆區開闢的記憶體空間),就會存在一塊記憶體空間被多次釋放的問題。
解決辦法
自己寫拷貝構造,讓拷貝構造後的對象中的成員指針變數指向一塊新的記憶體空間。
//
// Created by Administrator on 2023/4/25.
//
#include <iostream>
using namespace std;
// 深拷貝和淺拷貝
class Person {
public:
int p_age;
int *p_weight;
Person() {
cout << "無參構造" << endl;
}
Person(int age, int height) {
p_age = age;
p_weight = new int(height);
cout << "有參構造" << endl;
}
// 析構函數 用於釋放手動在堆區開闢的空間
~Person() {
if (p_weight != NULL) {
delete p_weight;
// 防止野指針
p_weight = NULL;
}
cout << "析構函數" << endl;
}
// 拷貝構造 不寫讓編譯器生成
// 防止 淺拷貝帶來的問題 自己寫拷貝構造 避免這個問題
Person(const Person &p) {
cout << "自己寫的拷貝構造,避免淺拷貝的問題" << endl;
p_age = p.p_age;
// 這是淺拷貝
// p_height = p.p_height; 自動生成的就是這樣
// 深拷貝 重新開一塊空間 防止出現重覆釋放的問題
p_weight = new int(*p.p_weight);
}
};
void test() {
Person p1(10, 120);
cout << "年齡為: " << p1.p_age << ", 體重為: " << *p1.p_weight << endl;
Person p2(p1);
cout << "年齡為: " << p2.p_age << ", 體重為: " << *p2.p_weight << endl;
// 會 先釋放p2 在釋放p1
// 釋放p2後析構函數會將 堆區中開闢的空間釋放了 p1在此執行析構 在此操作那塊記憶體就會報錯
}
int main() {
test();
return 0;
}