轉載自 天之痕
C++中的淺複製與深複製收藏
默認構造函數將作爲參數傳入的對象的每個成員變量複製到新對象的成員變量中,這被稱爲成員淺複製。這雖然對大多數成員變量可行,但對於指向自由存儲區中對象的指針成員變量不可行。
成員淺複製只是將對象成員變量的值複製到另一個對象中,兩個成員變量的指針最後指向同一個內存塊,當其中任何一個指針被delete時,將生成一個迷途指針,程序將處於危險之中。如圖:
假如舊對象指針成員變量所指堆內存被釋放後,此時新對象指針成員變量仍指向該內存塊,這是不合法的。這種情況的解決辦法是:創建自己的複製構造函數並根據需要來分配內存。分配內存後,可以將原對象的值複製到新內存中。這稱之爲深層複製。
程序實例如下:
- #include <iostream>
- using namespace std;
- class Cat
- {
- public:
- Cat();
- Cat(const Cat &);
- ~Cat();
- int GetAge() const { return *itsAge; }
- int GetWeight() const { return *itsWeight; }
- void SetAge(int age) { *itsAge=age; }
- private:
- int *itsAge; //實際編程並不會這樣做,
- int *itsWeight; //我僅僅爲了示範
- };
- Cat::Cat()
- {/*構造函數,在堆中分配內存*/
- itsAge=new int;
- itsWeight=new int;
- *itsAge=5;
- *itsWeight=9;
- }
- Cat::Cat(const Cat & rhs)
- {/*copy constructor,實現深層複製*/
- itsAge=new int;
- itsWeight=new int;
- *itsAge=rhs.GetAge();
- *itsWeight=rhs.GetWeight();
- }
- Cat::~Cat()
- {
- delete itsAge;
- itsAge=0;
- delete itsWeight;
- itsWeight=0;
- }
- int main()
- {
- Cat Frisky;
- cout << "Frisky's age: "<<Frisky.GetAge()<<endl;
- cout << "Setting Frisky to 6.../n";
- Frisky.SetAge(6);
- cout << "Create Boots from Frisky/n";
- Cat Boots=Frisky; //or Cat Boots(Frisky);
- cout << "Frisky's age: " <<Frisky.GetAge()<<endl;
- cout << "Boots' age : "<<Boots.GetAge()<<endl;
- cout << "Set Frisky to 7.../n";
- Frisky.SetAge(7);
- cout << "Frisky's age: "<<Frisky.GetAge()<<endl;
- cout << "Boots' age: "<<Boots.GetAge()<<endl;
- return 0;
- }
- //輸出:
- //Frisky's age: 5
- //Setting Frisky to 6...
- //Create Boots from Frisky
- //Frisky's age: 6
- //Boots' age : 6
- //Set Frisky to 7...
- //Frisky's age: 7
- //Boots' age: 6