C++的深複製與淺複製

上代碼,定義類:

// helloworld.h
{
public:
    explicit HelloWorld();
    HelloWorld(const HelloWorld &otherHW);
    void operator =(const HelloWorld &hw);
    ~HelloWorld();

    int *getPtr() const;

private:
    int *m_ptr;
};

// helloworld.cpp
HelloWorld::HelloWorld()
{
    m_ptr = new int(100);
}

HelloWorld::HelloWorld(const HelloWorld &otherHW)
{
    m_ptr = otherHW.getPtr();
}

void HelloWorld::operator =(const HelloWorld &hw)
{
    m_ptr = hw.getPtr();
}

HelloWorld::~HelloWorld()
{
    delete m_ptr;
}

int *HelloWorld::getPtr() const
{
    return m_ptr;
}

調用代碼:

int main() {
    HelloWorld hw1;
    HelloWorld hw2;
    cout<<"hw1"<<hw1.getPtr()<<endl;
    cout<<"hw2"<<hw2.getPtr()<<endl;
    return 0;
}

輸出:

hw1	0x7ffea3c02b10
hw2	0x7ffea3c02b20

假設存在拷貝賦值,即:

    hw1 = hw2;
    cout<<"hw1\t"<<hw1.getPtr()<<endl;
    cout<<"hw2\t"<<hw2.getPtr()<<endl;

程序會發生奔潰,因爲在operator =(const HelloWorld &hw)發生了淺拷貝m_ptr = hw.getPtr(),而HelloWorld的析構函數會delete m_ptr,因此在發生了拷貝賦值之後,兩個對象的m_ptr指向了同一個內存區域,調用兩次析構會刪除m_ptr兩次,因此造成程序奔潰。

解決方法可以如下:

void HelloWorld::operator =(const HelloWorld &hw)
{
//    m_ptr = hw.getPtr(); // error
    memcpy(m_ptr, hw.getPtr(), sizeof(int)); // ok
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章