c++構(gòu)造函數(shù)

構(gòu)造函數(shù)

引入

在c++的類中,構(gòu)造函數(shù)是一種特殊的成員函數(shù),在每次創(chuàng)建創(chuàng)建一個(gè)類的時(shí)候會(huì)默認(rèn)調(diào)用構(gòu)造函數(shù)進(jìn)行初始化工作。

構(gòu)造函數(shù)用來完成一些必要的初始化工作,有了構(gòu)造函數(shù)之后,就無需再單獨(dú)寫初始化函數(shù),并且也不必?fù)?dān)心忘記調(diào)用初始化函數(shù)。

基本概念

構(gòu)造函數(shù)具有如下幾個(gè)特點(diǎn)

  • 名字與類名相同,可以有參數(shù),但是不能有返回值(void也不行)
  • 作用是對(duì)對(duì)象進(jìn)行初始化工作,如給成員變量賦值等。
  • 如果定義類時(shí)沒有寫構(gòu)造函數(shù),系統(tǒng)會(huì)生成一個(gè)默認(rèn)的無參構(gòu)造函數(shù),默認(rèn)構(gòu)造函數(shù)沒有參數(shù),不做任何工作。
  • 如果定義了構(gòu)造函數(shù),系統(tǒng)不再生成默認(rèn)的無參構(gòu)造函數(shù)
  • 對(duì)象生成時(shí)構(gòu)造函數(shù)自動(dòng)調(diào)用,對(duì)象一旦生成,不能在其上再次執(zhí)行構(gòu)造函數(shù)
  • 一個(gè)類可以有多個(gè)構(gòu)造函數(shù),為重載關(guān)系

構(gòu)造函數(shù)

默認(rèn)無參構(gòu)造函數(shù)

下面來看一個(gè)簡單的例子。

class Complex {//復(fù)數(shù)類
private:
    double real, imag;//分別表示實(shí)部以及虛部
public:
    void set(double r, double i) {
        real = r;
        imag = i;
    }
};

對(duì)于上面的復(fù)數(shù)類,real表示實(shí)部,imag表示虛部,set(set(double r, double i))函數(shù)為初始化函數(shù),我們并沒有為其編寫構(gòu)造函數(shù),此時(shí)編譯系統(tǒng)將生成一個(gè)默認(rèn)的無參構(gòu)造函數(shù)。

假設(shè)有如下調(diào)用:

int main() {
    Complex c1;//默認(rèn)構(gòu)造函數(shù)被調(diào)用
    Complex* c2 = new Complex;//默認(rèn)構(gòu)造函數(shù)被調(diào)用
    return 0;
}

在對(duì)象生成的時(shí)候,編譯系統(tǒng)自動(dòng)調(diào)用默認(rèn)的無參構(gòu)造函數(shù)對(duì)其進(jìn)行初始化工作(什么都沒做),此時(shí)我們必須自己調(diào)用set(double r, double i)函數(shù)才能對(duì)其進(jìn)行初始化操作。

編寫構(gòu)造函數(shù)

接下來我們?yōu)樯厦娴念惥帉懸粋€(gè)構(gòu)造函數(shù)

class Complex {//復(fù)數(shù)類
private:
    double real, imag;//分別表示實(shí)部以及虛部
public:
    Complex(double r, double i = 0) {
        real = r;
        imag = i;
    }
};
int main() {
    Complex c1;//錯(cuò)誤,參數(shù)不匹配
    Complex* c2 = new Complex;//錯(cuò)誤,參數(shù)不匹配
    return 0;
}

當(dāng)我們?cè)谡{(diào)用上面的代碼生成對(duì)象c1、c2時(shí),編譯系統(tǒng)會(huì)給我們報(bào)錯(cuò)。原因是我們編寫的構(gòu)造函數(shù)需要接收至少一個(gè)參數(shù),而我們?cè)诔跏蓟臅r(shí)候沒有給出任何的參數(shù)。

對(duì)上面的代碼進(jìn)行如下的改動(dòng):

int main() {
    Complex c1(1);//OK
    Complex* c2 = new Complex(2,5);//OK
    return 0;
}

此時(shí)c1、c2就可以正常地生成。

  • 對(duì)于c1對(duì)象,用1來初始化實(shí)部,用缺省的0初始化虛部。
  • 對(duì)于c2對(duì)象,用2來初始化實(shí)部,用5初始化虛部。

構(gòu)造函數(shù)重載

對(duì)于同一個(gè)類,可以有多個(gè)構(gòu)造函數(shù),只要參數(shù)個(gè)數(shù)或類型不同就可,他們之間為重載的關(guān)系。

class Complex {//復(fù)數(shù)類
private:
    double real, imag;//分別表示實(shí)部以及虛部
public:
    //構(gòu)造函數(shù)
    Complex();
    Complex(double r);
    Complex(double r, double i);
    Complex(Complex c1, Complex c2);
};
Complex::Complex() {
    real = 0;
    imag = 0;
}
Complex::Complex(double r) {
    real = r;
    imag = 0;
}
Complex::Complex(double r, double i) {
    real = r;
    imag = i;
}
Complex::Complex(Complex c1, Complex c2) {
    real = c1.real + c2.real;
    imag = c1.imag + c2.imag;
}

在上面的類中,分別寫了四個(gè)構(gòu)造函數(shù)

  • Complex()無參構(gòu)造函數(shù),realimag都初始化為0
  • Complex(double r)real初始化為r,imag初始化為0
  • Complex(double r, double i)real初始化為r,imag初始化為i
  • Complex(Complex c1, Complex c2)real初始化為c1.real + c2.real,imag初始化為c1.imag + c2.imag

對(duì)于上面的類,假設(shè)我們有如下調(diào)用:

int main() {
    Complex c1;//調(diào)用Complex()構(gòu)造函數(shù)
    Complex c2(2);//調(diào)用Complex(double r)構(gòu)造函數(shù)
    Complex c3(2, 3);//調(diào)用Complex(double r, double i)構(gòu)造函數(shù)
    Complex c4(c1, c2);//Complex(Complex c1, Complex c2)構(gòu)造函數(shù)
    return 0;
}
  • 對(duì)于c1對(duì)象,調(diào)用Complex()無參構(gòu)造函數(shù),將realimag都初始化為0
  • 對(duì)于c2對(duì)象,調(diào)用Complex(double r)構(gòu)造函數(shù),將real初始化為2imag初始化為0
  • 對(duì)于c3對(duì)象,調(diào)用Complex(double r, double i)構(gòu)造函數(shù),將real初始化為2,imag初始化為3
  • 對(duì)于c4對(duì)象,調(diào)用Complex(Complex c1, Complex c2)real初始化為c1.real + c2.real=2,imag初始化為c1.imag + c2.imag=0

構(gòu)造函數(shù)在數(shù)組中的使用

下面我們通過一個(gè)實(shí)例來查看對(duì)與對(duì)象數(shù)組是如何調(diào)用構(gòu)造函數(shù)進(jìn)行初始化的。

class Complex {//復(fù)數(shù)類
private:
    double real, imag;//分別表示實(shí)部以及虛部
public:
    //構(gòu)造函數(shù)
    Complex() {
        cout << "無參構(gòu)造函數(shù)初始化" << endl;
    }
    Complex(double r) {
        cout << "一個(gè)參數(shù)的構(gòu)造函數(shù)初始化" << endl;
    }
    Complex(double r, double i) {
        cout << "兩個(gè)參數(shù)的構(gòu)造函數(shù)初始化" << endl;
    }
};

我們?yōu)樯厦娴念悓懥巳齻€(gè)構(gòu)造函數(shù),在調(diào)用無參構(gòu)造函數(shù)時(shí)輸出無參構(gòu)造函數(shù)初始化,調(diào)用一個(gè)參數(shù)的構(gòu)造函數(shù)時(shí)輸出一個(gè)參數(shù)的構(gòu)造函數(shù)初始化,調(diào)用兩個(gè)構(gòu)造函數(shù)初始化時(shí)輸出兩個(gè)參數(shù)的構(gòu)造函數(shù)初始化

假設(shè)我們有如下的對(duì)象生成:

int main() {
    cout << "array1" << endl;
    Complex array1[3];

    cout << "array2" << endl;
    Complex array2[3] = { 1,2 };

    cout << "array3" << endl;
    Complex array3[3] = { 1,Complex(1,2) };

    cout << "array4" << endl;
    Complex* array4 = new Complex[3];
    
    cout << "array5" << endl;
    Complex* array5[3] = { new Complex(1),new Complex(2,3) };
    
    delete[]array4;
    return 0;
}
  • 對(duì)于array1生成的三個(gè)對(duì)象,我們沒有為其指定參數(shù),所以都調(diào)用無參構(gòu)造函數(shù)進(jìn)行初始化。
  • 對(duì)于array2生成的三個(gè)對(duì)象,我們指定了前兩個(gè)的參數(shù)表為12,所以調(diào)用一個(gè)參數(shù)的構(gòu)造函數(shù)進(jìn)行初始化,第三個(gè)對(duì)象沒有指定參數(shù),所以調(diào)用無參構(gòu)造函數(shù)進(jìn)行初始。
  • 對(duì)于array3生成的三個(gè)對(duì)象,第一個(gè)對(duì)象參數(shù)為1,所以調(diào)用無參構(gòu)造函數(shù)初始化,第二個(gè)對(duì)象參數(shù)為(1,2),所以調(diào)用兩個(gè)參數(shù)的構(gòu)造函數(shù)初始化,對(duì)于第三個(gè)對(duì)象,我們沒有指定參數(shù),所以調(diào)用無參構(gòu)造函數(shù)初始化。
  • array4為一個(gè)Complex類的指針,通過new運(yùn)算符動(dòng)態(tài)分配三個(gè)對(duì)象,并將其首地址返回給array4,在此我們并沒有為new出來的三個(gè)對(duì)象指定初始化參數(shù),所以三個(gè)對(duì)象都調(diào)用無參構(gòu)造函數(shù)初始化。
  • array5為一個(gè)Complex類的指針數(shù)組,包含三個(gè)指針對(duì)象。第一個(gè)new Complex(1)生成了一個(gè)對(duì)象,且參數(shù)為1,所以調(diào)用一個(gè)參數(shù)的構(gòu)造函數(shù);第二個(gè)元素通過new Complex(2,3)生成一個(gè)對(duì)象,且參數(shù)為(2,3),所以調(diào)用兩個(gè)參數(shù)的構(gòu)造函數(shù);第三個(gè)我們沒有為其動(dòng)態(tài)分配內(nèi)存空間,所以不會(huì)導(dǎo)致對(duì)象的生成,僅存在一個(gè)對(duì)象指針。所以array5僅生成了兩個(gè)對(duì)象。

對(duì)于上面的程序,我們可以得到如下的運(yùn)行結(jié)果:

array1
無參構(gòu)造函數(shù)初始化
無參構(gòu)造函數(shù)初始化
無參構(gòu)造函數(shù)初始化
array2
一個(gè)參數(shù)的構(gòu)造函數(shù)初始化
一個(gè)參數(shù)的構(gòu)造函數(shù)初始化
無參構(gòu)造函數(shù)初始化
array3
一個(gè)參數(shù)的構(gòu)造函數(shù)初始化
兩個(gè)參數(shù)的構(gòu)造函數(shù)初始化
無參構(gòu)造函數(shù)初始化
array4
無參構(gòu)造函數(shù)初始化
無參構(gòu)造函數(shù)初始化
無參構(gòu)造函數(shù)初始化
array5
一個(gè)參數(shù)的構(gòu)造函數(shù)初始化
兩個(gè)參數(shù)的構(gòu)造函數(shù)初始化
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容