上代碼,定義類:
// 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
}