對象的深拷貝和淺拷貝

在copy一個對象時(用一個對象去初始化另一個對象),會調用類中的拷貝構造函數。若是咱們本身沒有在類裏面寫拷貝構造函數,則C++編譯器會調用默認的拷貝構造函數。ios

 

淺拷貝:若是類定義的對象包含的某個成員是動態內存分配產生的(指針變量成員),你先用該類定義了一個對象1,而後又用這個對象1去初始化另一個對象2。若是在類裏面,沒有本身寫拷貝構造函數,C++編譯器會調用默認的拷貝構造函數,只能將對象1的成員的值賦給對象2的成員,對象1成員指向的內存並無被複制,也就是說對象1指針成員和對象2指針成員指向的是同一塊內存。這樣在析構對象時,先析構對象2,對象2指針成員指向的內存被free。因爲對象1指針成員和對象2指針成員的值同樣,指向的是同一塊內存,析構對象1的指針成員時,它所指向的那塊內存以前已經被對象2的指針成員free,無法再次free,就會出現宕機(down機),這就是淺拷貝問題。淺拷貝問題在編譯階段不會出問題,只有當程序運行的時候纔會發現問題。函數

                                                     

                                                                            淺拷貝問題圖解spa

 

若是要解決淺拷貝問題,那就必須深拷貝。所謂的深拷貝,就是說不只將對象1的值拷貝給對象2,並且要將對象1指針成員指向的內存空間也要賦值一份給對象2。這時候,咱們就不能再用C++編譯器給咱們提供的默認拷貝構造函數,必須本身寫一份拷貝構造函數。指針

關於淺拷貝和深拷貝問題,能夠參考如下代碼:code

 1 //myname.h
 2 #pragma once
 3 class myname  4 {  5 public:  6     myname(const char*);  7     myname(const myname&);  8     ~myname(void);  9     void printN(); 10 
11 private: 12     int len; 13     char* p; 14 }; 15 
16 
17 //myname.cpp
18 #include "myname.h"
19 #include "string.h"
20 #include "malloc.h"
21 #include <iostream>
22 
23 #define _CRT_SECURE_NO_WARNINGS
24 
25 //構造函數
26 myname::myname(const char* myp) 27 { 28     len=strlen(myp); 29     p=(char*)malloc(sizeof(char)*(len+1)); 30  strcpy(p,myp); 31 } 32 
33 //拷貝構造函數。若是不本身寫該函數,C++編譯器會調用默認的拷貝構造函數,則會發生淺拷貝。本身寫了該函數,C++編譯器就會調用該函數,發生的是深拷貝
34 myname::myname(const myname& n) 35 { 36     len=n.len; 37     p=(char*)malloc(sizeof(char)*(len+1)); 38  strcpy(p,n.p); 39 } 40 
41 
42 void myname::printN() 43 { 44     std::cout<<"name:"<<p<<std::endl; 45 } 46 
47 
48 myname::~myname(void) 49 { 50     free(p); 51     p=NULL; 52     len=0; 53 } 54 
55 
56 //main函數
57 #include<iostream>
58 #include "myname.h"
59 
60 using namespace std; 61 
62 int main() 63 { 64     
65     myname name1("Zhang wuji"); 66  myname name2(name1); 67  name2.printN(); 68     
69 
70     return 0; 71 }
相關文章
相關標籤/搜索