如果我們沒有提供拷貝構造函數,沒有重載=操作符,vector 對我們的 mc 對象進行的簡單的淺拷貝,將拷貝的對象插入到容器中,導致我們的 mc 對象的 data 指針和容器中mc 對象的拷貝對象中的 data 指針都指向了我們在堆區分配的內存,當函數結束,兩個對象都調用了析構函數,先調用析構函數的對象成功釋放了堆區內存,后調用析構函數的對象一釋放,程序掛掉了。
原因在於兩個指針指向了同一塊堆區內存,這樣會導致不可預知的結果,函數結束其中一個調用析構函數,銷毀了 data 指向的內存空間,而另一個對象析構的時候就會掛掉。
問題的解決辦法就是,給我們的對象提供一個拷貝構造函數,並且重載=操作符,兩個指針分別指向自己的那一塊內存,互不影響。
#include <iostream> #include <vector> using namespace std; class Person { public: Person(char* name, int age) { this->pName = new char[strlen(name) + 1]; strcpy_s(this->pName, strlen(name) + 1, name); this->mAge = age; } // 增加拷貝構造函數 Person(const Person& p) { this->pName = new char[strlen(p.pName) + 1]; strcpy_s(this->pName, strlen(p.pName) + 1, p.pName); this->mAge = p.mAge; } // 重載 operator=操作符 Person& operator=(Person& p) { if (this->pName == NULL) { delete[] this->pName; } this->pName = new char[strlen(p.pName) + 1]; strcpy_s(this->pName, strlen(p.pName) + 1, p.pName); this->mAge = p.mAge; return *this; } ~Person() { if (this->pName == NULL) { delete[] this->pName; } } public: char* pName; // 指針容易淺拷貝的問題 int mAge; }; void test01() { Person a("aaa", 20); vector<Person> vPerson; vPerson.push_back(a); } int main() { test01(); getchar(); return 0; }
