C++ 深拷贝
系統(tǒng)提供默認(rèn)的拷貝構(gòu)造器,一經(jīng)定義不再提供。但系統(tǒng)提供的默認(rèn)拷貝構(gòu)造器是 等位拷貝,也就是通常意義上的淺拷貝。如果類中包含的數(shù)據(jù)元素全部在棧上,淺拷貝 也可以滿足需求的。但如果堆上的數(shù)據(jù),則會發(fā)生多次析構(gòu)行為。
#include <iostream> #include <cstdlib>using namespace std;int strlen(const char s[]){int len = 0;while (s[len]){len++;}return len; // 返回?cái)?shù)組str中首個值為null的元素的下標(biāo)值 }char* strcpy(char *p, const char *s){char *t = p;while (*p++ = *s++){}return t; }class Teacher{public://有參數(shù)的構(gòu)造函數(shù)Teacher(int id, const char *name){cout << "調(diào)用了Teacher 的構(gòu)造函數(shù)" << endl;//是給id 賦值m_id = id;//給姓名賦值int len = strlen(name);m_name = (char*)malloc(len + 1);strcpy(m_name, name);}//顯示寫一個拷貝構(gòu)造函數(shù)//通過顯示拷貝構(gòu)造函數(shù)提供了深拷貝的動作Teacher(const Teacher &another){m_id = another.m_id; //給id賦值int len = strlen(another.m_name);m_name = (char*)malloc(len + 1);strcpy(m_name, another.m_name);}~Teacher() {//在構(gòu)造函數(shù)中, 已經(jīng)開辟了內(nèi)存 所以為了防止泄露//在析構(gòu)函數(shù)中,在對象銷毀之前,把m_name的內(nèi)存釋放掉if (m_name != NULL) {free(m_name);m_name = NULL;cout << "釋放掉了m_name" << endl;}}private:int m_id;char *m_name; };int main(void){Teacher t1(1, "vvcat");//如果不提供一個顯示的拷貝構(gòu)造函數(shù), 通過系統(tǒng)自帶的默認(rèn)拷貝構(gòu)造函數(shù)Teacher t2(t1); //會調(diào)用t2的拷貝構(gòu)造函數(shù),將t1的值拷貝給t2 }注:
如果在拷貝構(gòu)造函數(shù)沒有對變量進(jìn)行深拷貝的動作而使用了淺拷貝的動作,程序會報(bào)錯或者會因?yàn)?char * 變量因?yàn)闆]有得到釋放,導(dǎo)致程序崩潰。
以下是,錯誤舉例:
總結(jié)
- 上一篇: C++ 拷贝构造函数应用场景
- 下一篇: C++ 构造函数的初始化列表