構造函數 拷貝函數 賦值構造函數


#ifndef _SAMPLE_H_
#define _SAMPLE_H_
#include <stdio.h>
#include <string>struct QQ
{
QQ() { qqNum = 123456; qqPassword = "xyzabc123"; }
int qqNum;
std::string qqPassword;
};


//以下A,B,C,D分別爲:
//A: 沒有實現拷貝構造函數和賦值構造函數,所以會自動生成默認的拷貝構造函數和賦值構造函數
//B: 與A相同,但數據成員存在堆分配情況,這樣默認的拷貝構造函數只會拷貝指針而不會拷貝指針所指向的對象
//C: 實現了拷貝構造函數和賦值構造函數
//D: 與C相同,但存在堆分配情況,因此也必須深拷貝


//什麼是深拷貝,什麼是淺拷貝,自己去查下
//如果不自己去實現拷貝構造函數和賦值構造函數,那麼默認就是淺拷貝。淺拷貝在類中存在指針(比如給指針new對象,即堆分配過程)時,是危險的
//因爲只拷貝了指針,而不會去拷貝指針所new的對象,這樣當源對象被析構時,你拷貝的指針就會指向一個已被釋放了的內存


struct TA
{
TA()

tQq.qqNum = 789456;
} //struct和class的區別就是:struct所有的成員都是public的,其餘一樣
~TA() { }


QQ tQq;//注意,這是變量是在棧上分配內存的
};


struct TB
{
TB() 

pQQ = new QQ();
pQQ->qqNum = 789456;
}
~TB(){ delete pQQ; }//堆分配的內存一定要自己釋放


QQ* pQQ;//注意,只定義了一個指針。構造函數給這個指針在堆上分配了一個對象,並把對象的地址賦給了這個指針
};


class TC
{
public:
TC() 

tQq.qqNum = 456123;
}
TC( const TC& otherC )//拷貝構造函數的形式必須這樣定義
{
tQq = otherC.tQq;
}
~TC() { }


TC& operator = ( const TC& otherC )//賦值構造函數實際上就是重載"="等號操作符
{
tQq = otherC.tQq;
return *this;
}


private:
QQ tQq;
};


class TD
{
public:
TD()

pQq = new QQ();
pQq->qqNum = 123789;
}
TD( const TD& otherD )
{
pQq = new QQ();
//pQq = otherD.pQq;//思考:爲什麼不能這樣賦值
*pQq = *(otherD.pQq);
}
~TD(){ delete pQq; }


TD& operator = ( const TD& otherD )
{
*(pQq) = *(otherD.pQq);
return *this;
}
QQ* pQq;
};

#endif

// LessonSet.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "Sample.h"
int _tmain(int argc, _TCHAR* argv[])
{
//如同默認構造函數一樣,如果不定義,編譯器會自動生成一個默認的拷貝構造函數和賦值構造函數
//自己調試,看它們各自調用的是什麼構造函數


TA a1;  //調用默認構造函數
TA a2(a1);  //調用拷貝構造函數
TA a3 = a1;  //調用拷貝構造函數,注意:這裏的等號爲什麼不調用=賦值操作符?
TA a4;
a1.tQq.qqNum = 1000;
a4 = a1;  //調用賦值構造函數,注意:這種賦值調用的就是=賦值操作符(賦值構造函數)


//下同


TB b1;
TB b2( b1 );
TB b3 = b1;
TB b4;
b4 = b1;


TC c1;
TC c2( c1 );
TC c3 = c1;
TC c4;
c4 = c1;


TD d1;
TD d2( d1 );
TD d3 = d1;
TD d4;
d4 = d1;


getchar();
return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章