淺拷貝與深拷貝
淺拷貝與深拷貝
在上一節講解的拷貝建構函式的例子Circle類中,拷貝的策略都是與系統預設的策略一致,即把原有物件中成員依次拷貝給新物件中對應的成員,既然如此,我們為何還要自己定義呢?原因在於,簡單的將所有情況都按照這種簡單的方式初始化,難免有不同的情況,出現問題。
例如,剛才的Circle類中,如果成員變數中加一個指標成員,初始化中需要動態開闢記憶體,則會出現極大的安全隱患,程式碼如下:
/********************************** //Des:C++教程配套程式 //Author:Huang //CopyRight:www.dotcpp.com //Date:2017/8/26 **********************************/
include
include
using namespace std;
define PI 3.1415
class Circle { private: double R; char *str; public: Circle(double R,char *str); ~Circle(); double area(); double girth(); }; Circle::~Circle() { delete []str; } Circle::Circle(double R,char *str) { cout<<"Constructor"<<endl; this->R = R; this->str = new char[strlen(str)+1]; strcpy(this->str,str); cout<R<<" "<str<
double Circle::area() { return PI*R*R; } double Circle::girth() {
return 2*PI*R;
} int main() {
Circle A(5,"NO.1 Old class");
Circle B(A);
return 0;
} 為了驗證,在Circle類中,我們增加了一個指標成員,並且在建構函式中對其初始化,同時沒有自定義拷貝建構函式。那麼在主函式中Circle B(A);的這句話將A物件賦值給B物件,將呼叫預設生成的拷貝建構函式,執行後,程式如下圖報錯
qian.png
而實際上的原因在於,預設的拷貝建構函式僅僅是進行資料賦值,並不能為指標開闢記憶體空間,相當於程式碼:
This->str = str;
那麼本質上,也就是兩個指標指向一塊堆空間。已經違背了我們的初衷。那麼在程式結束的時候,兩個物件回收的時候,會呼叫自己的解構函式,釋放這塊記憶體空間,由於兩個物件要呼叫兩次,即delete兩次,就會出現錯誤!
所以,當類中有指標型別時,依靠預設的拷貝建構函式的方法,已經無法滿足我們的需求,必須定義一個特定的拷貝建構函式,即不僅可以進行資料的拷貝,也可以為成員分配記憶體空間,實現真正的拷貝,也叫做深拷貝,這就是深拷貝建構函式。
深拷貝建構函式實現:
include
include
using namespace std;
define PI 3.1415
class Circle { private: double R; char *str; public: Circle(double R,char *str); Circle(Circle &A); ~Circle(); double area(); double girth(); };
Circle::~Circle() { delete []str; cout<<"Call Destructor"<<endl; } Circle::Circle(Circle &A) { cout<<"Copy Constructor"<<endl; this->R = A.R; this->str = new char[strlen(A.str)+1]; strcpy(this->str,A.str); } Circle::Circle(double R,char *str) { cout<<"Constructor"<<endl; this->R = R; this->str = new char[strlen(str)+1]; strcpy(this->str,str); }
double Circle::area() { return PI*R*R; } double Circle::girth() { return 2*PI*R; } int main() {
Circle A(5,"NO.1 Old class");
Circle B(A);
return 0;
}
其實現原理與帶引數的建構函式類似,在賦值之前開闢足夠的記憶體空間,來真正完成完整的拷貝,這就是所謂的“深拷貝”。
請大家理解後上機實驗!
相關文章
- 淺談深拷貝與淺拷貝?深拷貝幾種方法。
- JS深拷貝與淺拷貝JS
- python深拷貝與淺拷貝Python
- Python淺拷貝與深拷貝Python
- 淺拷貝&深拷貝
- 深入淺出深拷貝與淺拷貝
- 深拷貝、淺拷貝與Cloneable介面
- 談談深拷貝與淺拷貝
- 賦值、淺拷貝與深拷貝賦值
- React之淺拷貝與深拷貝React
- 淺拷貝和深拷貝
- 深拷貝和淺拷貝
- 深入淺出的“深拷貝與淺拷貝”
- 圖解 Python 淺拷貝與深拷貝圖解Python
- JavaScript中的淺拷貝與深拷貝JavaScript
- 淺拷貝與深拷貝程式碼(javascript)JavaScript
- ES6深拷貝與淺拷貝
- 淺拷貝與深拷貝的實現
- 【JavaScript】物件的淺拷貝與深拷貝JavaScript物件
- 【JS】深拷貝與淺拷貝,實現深拷貝的幾種方法JS
- iOS深拷貝和淺拷貝iOS
- js 深拷貝和淺拷貝JS
- JavaScript淺拷貝和深拷貝JavaScript
- Java深拷貝和淺拷貝Java
- 物件深拷貝和淺拷貝物件
- JavaScript深拷貝和淺拷貝JavaScript
- javascript 淺拷貝VS深拷貝JavaScript
- js 淺拷貝和深拷貝JS
- python 指標拷貝,淺拷貝和深拷貝Python指標
- 理解JS中的淺拷貝與深拷貝JS
- Java 輕鬆理解深拷貝與淺拷貝Java
- 淺探js深拷貝和淺拷貝JS
- java深克隆(深拷貝)和淺克隆(淺拷貝)Java
- go slice深拷貝和淺拷貝Go
- js之淺拷貝和深拷貝JS
- ECMAScript-淺拷貝和深拷貝
- C++淺拷貝和深拷貝C++
- 實現物件淺拷貝、深拷貝物件