C++ STL 之 容器的深拷貝和淺拷貝


如果我們沒有提供拷貝構造函數,沒有重載=操作符,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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM