http://blog.csdn.net/hr10707020217/article/details/8653598
2013
構(gòu)造函數(shù)、復(fù)制構(gòu)造函數(shù)和賦值操作符在生成對象和對象之間的復(fù)制時(shí)用到。如果類中沒有顯式定義這三種函數(shù),那編譯器通常會為我們定義(合成)。如果類中定義了一個(gè)帶參數(shù)的構(gòu)造函數(shù),那么編譯器就不會再自動合成默認(rèn)構(gòu)造函數(shù)(空參數(shù)的構(gòu)造函數(shù)),這需要我們顯式定義。C++ Primer中對復(fù)制控制操作講述得比較多,要理解起來還得動手實(shí)際的操作一下,看看編譯器是如何實(shí)現(xiàn)這些操作的,下面的操作使用VC++6.0編譯器。
#include <iostream>
using namespace std;
class classA
{
public:
classA() //默認(rèn)構(gòu)造函數(shù)
{
}
classA(int a) //帶參數(shù)的構(gòu)造函數(shù)
{
}
classA(const classA& ma) //復(fù)制構(gòu)造函數(shù)
{
}
classA &operator=(const classA& ma) //賦值操作符
{
this->num = ma.num;
return *this;
}
~classA() //析構(gòu)函數(shù)
{
}
void print() //成員函數(shù)
{
}
private:
int num; //數(shù)據(jù)成員
};
int main()
{
classA obj1;
classA obj2(1);
classA *pobj3 = new classA;
classA(2);
classA obj4(obj2);
classA obj5 = obj2;
classA obj6 = classA(3);
classA obj7 = classA(obj2);
obj1 = obj2;
obj1 = classA(obj2);
obj1 = classA(6);
classA obj8 = 8;
obj8 = 9;
return 0;
}
總結(jié):定義一個(gè)類類型的對象,總會使用構(gòu)造函數(shù)生成一個(gè)對象的空間。調(diào)用哪種構(gòu)造函數(shù)(默認(rèn)構(gòu)造函數(shù)、帶參數(shù)的構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù))根據(jù)傳入的實(shí)參決定??諈?shù)就調(diào)用默認(rèn)構(gòu)造函數(shù)(如語句1),單個(gè)本類類型參數(shù)的就調(diào)用復(fù)制構(gòu)造函數(shù)(如語句5),其它參數(shù)形式調(diào)用對應(yīng)的類中定義的構(gòu)造函數(shù)(如語句2)。如果對象已經(jīng)存在,兩個(gè)對象之間的賦值操作調(diào)用的是賦值操作符(如語句9)。
C++ Primer 第四版中文版409的13.1.2中說復(fù)制構(gòu)造函數(shù)“因?yàn)橛糜谙蚝瘮?shù)傳遞對象和從函數(shù)返回對象,該構(gòu)造函數(shù)一般不應(yīng)該設(shè)置為explicit”,想了半天這句話,沒有一個(gè)所以然來。實(shí)際操作一下:
在VC++6.0編譯器中,嘗試在復(fù)制構(gòu)造函數(shù)前面加上explicit修飾(explicit classA(const classA& ma)),如果不執(zhí)行classA obj5 = obj2這種類型的復(fù)制初始化操作,可以編譯通過。如果有這條語句就會報(bào)“cannot convert from 'class classA' to 'class classA'。No copy constructor available for class 'classA'”,這個(gè)錯(cuò)誤提示模糊,很難理解。
在VC++2008(VC9.0)編譯器中,嘗試在復(fù)制構(gòu)造函數(shù)前面加上explicit修飾,如果不執(zhí)行classA obj5 = obj2這種類型的復(fù)制初始化操作,還是可以編譯通過。如果有這條語句就會報(bào)“ no copy constructor available or copy constructor is declared 'explicit'”,這個(gè)錯(cuò)誤提示就明晰很多。
通過上述的理解,如果構(gòu)造函數(shù)(帶單參數(shù)的構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù))前面用explicit修飾:explicit classA(Type a),其中Type是參數(shù)類型。那么編譯器就會不執(zhí)行這種類型的操作:classA obj = a,只能是顯式的使用直接初始化操作:classA obj(a) 。這樣子就能夠解釋為什么復(fù)制構(gòu)造函數(shù)不應(yīng)該修飾為explicit了,這是由于按照使用習(xí)慣,復(fù)制構(gòu)造函數(shù)可以采用復(fù)制初始化形式執(zhí)行(語句6)。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點(diǎn)擊舉報(bào)。