C++ deep copy exam questions
C++ deep copy 考題
使用 C++的「=」複製物件時,預設的複製方式是 memberwise assignment,例如執行o1 = o2 時,會將 o2 的各 member variables 複製至 o1,若 member variables 中有 pointer
時,則直接複製 pointer,因此,o1 與 o2 會共用此 pointer 所指向的物件,此後若變
更 o1 的內容時,也可能會變更 o2,效果相當於 shallow copy。在某些應用場合,我
們希望支援 deep copy,也就是當執行 o1 = o2 時,o1 應該擁有獨立的記憶體區域,
而不與 o2 共用。在以下程式中,Rectangle 類別使用 pointer 指向一個 Point(點),並
使用整數儲存 width、height,分別代表矩形的點座標,以及寬度及高度。請寫出:
operator = 的實作,使得在執行 Rectangle 的「=」時,自動產生 deep copy 的效果。
(20 分)
destructor 的實作,避免 memory leak。(5 分)
class Rectangle {
public:
Rectangle(int x=0, int y=0, int w=0, int h=0)
: width(w), height(h) { point = new Point(x, y); }
...
void print() {
cout << "Rectangle x=" << point->getX() << " y=" << point->getY()
<< " width=" << width << " height=" << height << endl;
}
Rectangle operator=(Rectangle rhs)
{ ...
}
private:
Point *point;
int width;
int height;
};
在這個情況下,我們需要實作自定義的複製建構子(copy constructor)、賦值運算子(assignment operator)以及解構函數(destructor)以實現深度複製和避免記憶體洩漏。
首先,讓我們討論解構函數。解構函數用於釋放在物件生命週期結束時配置的記憶體。在你的 `Rectangle` 類別中,你需要刪除 `point` 指向的 `Point` 物件,以確保沒有記憶體洩漏。這是解構函數的實作:
```cpp
Rectangle::~Rectangle() {
delete point;
}
```
接下來,讓我們討論賦值運算子的實作,以實現深度複製。在賦值運算子中,你需要建立一個新的 `Point` 物件和深度複製 `point` 指向的 `Point` 物件。然後,你需要複製 `width` 和 `height`。最後,你需要返回 `*this`,以支援連續賦值。這是賦值運算子的實作:
```cpp
Rectangle& Rectangle::operator=(const Rectangle& rhs) {
if (this == &rhs) {
return *this; // 避免自我賦值
}
delete point; // 釋放先前的 point 資源
point = new Point(rhs.point->getX(), rhs.point->getY());
width = rhs.width;
height = rhs.height;
return *this;
}
```
這個實作會在賦值時進行深度複製,並適當地釋放先前的記憶體。
最後,不要忘記修改你的 copy constructor 以支援深度複製,以及合適的建構子和解構函數,以確保物件的完整生命週期。確保使用上述的解構函數和賦值運算子,避免記憶體洩漏,並實現深度複製
Comments
Post a Comment