淺拷貝構造函數與深拷貝構造函數
阿新 • • 發佈:2018-09-16
對象指針 end amp base return 構造 原因 ase argc
1.淺拷貝構造函數
#include <iostream> using namespace std; class Base { public: int x; }; class Object : public Base { public: Object(int a,int b) { this->a = a; this->b = b; } Object(const Object &other): Base(other) //手動添加的拷貝構造函數,對基類拷貝構造函數 { cout<< "this is copy+" << endl; this->a = other.a; this->b = other.b; } private: int a; int b; }; int main(int argc, char * argv[]) { Object obja(1, 2); obja.x = 123; Object objb(obja); system("pause"); return 0; }
淺拷貝構造函數:1.淺拷貝構造函數中必須對每個成員變量進行拷貝;
2.繼承的類,必須對父類進行拷貝;
3.淺拷貝構造函數可省略,系統會有默認拷貝構造函數,就是對類的成員變量進行一一拷貝;
2.深拷貝構造函數-必須實現構造函數
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Object { public: Object(char * str) { m_size = strlen(str)+1; m_buf = new char[m_size]; strcpy(m_buf,str); printf("%s\n",m_buf); } ~Object() { delete[] m_buf; } private: char *m_buf; int m_size; }; int main(int argc, char * argv[]) { Object obja("hello world"); Object objb(obja); system("pause"); return 0; }
上述代碼在析構時,出現錯誤:
主要原因是因為使用了系統的默認拷貝構造函數,相當於執行了以下代碼:
objb.m_buf = obja.m_buf;
objb.m_size = obja.m_buf;
這樣兩個對象指針,指向了同一塊內存;
析構時,先析構了obja,指向的內存被釋放,再析構objb時,發現內存已經被釋放,導致程序崩潰;
因此,此時需要手動寫一個拷貝構造函數,目的是拷貝數據,而不是拷貝指針;見如下代碼:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Object { public: Object(char * str) { m_size = strlen(str)+1; m_buf = new char[m_size]; strcpy(m_buf,str); printf("%s\n",m_buf); } ~Object() { delete[] m_buf; } Object(const Object &other) { m_size = other.m_size; m_buf = new char[m_size]; strcpy(m_buf,other.m_buf); } private: char *m_buf; int m_size; }; int main(int argc, char * argv[]) { Object obja("hello world"); Object objb(obja); system("pause"); return 0; }
上述代碼中的紅色部分,手動實現的拷貝構造函數中申請一塊新的內存,然後對數據進行拷貝。
淺拷貝構造函數與深拷貝構造函數