在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 }