概念
- 成員函數(shù)的一種
- 名字與類名相同,可以有參數(shù),不能有返回值(void 也不行)
- 作用是對對象進(jìn)行初始化,如給成員變量賦初值
- 如果定義類的時候沒有寫構(gòu)造函數(shù),則編譯器生成一個默認(rèn)的無參數(shù)的構(gòu)造函數(shù)
- 默認(rèn)的構(gòu)造函數(shù)無參數(shù),不做任何操作.
- 如果定義了構(gòu)造函數(shù),則編譯器不生成默認(rèn)的無參數(shù)的構(gòu)造函數(shù).
- 對象生成的時候構(gòu)造函數(shù)自動被調(diào)用. 對象一旦生成, 就再也不能在其上執(zhí)行構(gòu)造函數(shù)
- 一個類可以有多個構(gòu)造函數(shù)
- 注意: 對象初始化時在內(nèi)存的分配并不是由構(gòu)造函數(shù)來完成挟纱,構(gòu)造函數(shù)只是執(zhí)行對象的初始化的工作育谬。
- 為什么需要構(gòu)造函數(shù):
- 構(gòu)造函數(shù)執(zhí)行必要的初始化工作,有了構(gòu)造函數(shù),就不必專門再寫初始化函數(shù),也不用再擔(dān)心忘記調(diào)用初始化函數(shù)冤狡。
- 有時候?qū)ο鬀]被初始化就使用,會導(dǎo)致程序出錯泄私。
class Complex{
private:
double real,image;
public:
void Set(double r,double i);
};
Complex c1;//調(diào)用默認(rèn)生成的構(gòu)造函數(shù)
Complex * pc = new Complex;
class Comples{
private:
double real,image;
public:
Complex( double r,double i = 0);//自定義構(gòu)造函數(shù)欺缘,這個時候就不會再生成默認(rèn)的構(gòu)造函數(shù)。
};
Complex::Complex( double r,double i){
real = r;image = i;
}
//調(diào)用
Complex c1;//error 箭阶,缺少構(gòu)造函數(shù)的參數(shù)
Complex *pc = new Complex;//error虚茶,沒有參數(shù)
Complex c1(2); //OK
Complex c1(2,4),c2(3,5); //OK
Complex *pc = new Complex(3,4);//OK
- 一個類可以有多個構(gòu)造函數(shù),參數(shù)個數(shù)或者類型不同
class Complex{
private:
double real,imag;
public:
void Set(double r,double i);
Complex(double r,double i);
Complex(double r);
Complex(Complex c1,Complex c2);
};
Complex::Complex(double r,double i)
{
real = r; imag = i;
}
Complex::Complex(double r)
{
real = r; imag = 0;
}
Complex::Complex(Complex c1, Complex c2)
{
real = c1.real + c2.real;
imag = c1.imag + c2.imag;
}
Complex c1(3),c2(1,0),c3(c1,c2);
- 構(gòu)造函數(shù)在數(shù)組中的使用
class CSample{
int x;
public:
CSample() {
cout<<"Constructor 1 Called" <<endl;
}
CSample(int n){
x = n;
cout<<"Constructor 2 Called"<<endl;
}
}
//調(diào)用
int main(){
//創(chuàng)建 CSample 的數(shù)組仇参,由于沒有傳遞任何參數(shù)嘹叫,默認(rèn)是用無參數(shù)的構(gòu)造函數(shù)進(jìn)行初始化
CSample array1[2];
cout<<"step1"<<endl;
//傳遞了兩個參數(shù),所以兩個元素都是由有參數(shù)的構(gòu)造函數(shù)來進(jìn)行初始化
CSample array2[2] = {4,5};
cout<<"step2"<<endl;
//第一個元素使用有參數(shù)诈乒,第二個使用無參數(shù)
CSample array3[2] = {3};
cout<<"step3"<<endl;
//兩個都為無參數(shù)
CSample * array4 = new Sample[2];
delete []array4;
return();
}
- 構(gòu)造函數(shù)在對象數(shù)組與指針數(shù)組之間的區(qū)別
class Test {
public:
Test(itn n){}
Test(itn n ,int m){}
Test(){}
};
//初始化對象數(shù)組罩扇,每個元素都會調(diào)用構(gòu)造函數(shù),如果有參數(shù)調(diào)用有參數(shù)的構(gòu)造函數(shù)怕磨,如果沒有參數(shù)則調(diào)用無參構(gòu)造函數(shù)
Test array1[3] = {1,Test(1,2)};
Test array2[3] = {Test(2,3),Test(1,2),1};
//初始化指針數(shù)組喂饥,以為數(shù)組的內(nèi)容都是指針,不會自動調(diào)用對象的構(gòu)造函數(shù)肠鲫,只有調(diào)用才會生成员帮,不調(diào)用指針就會為 NULL。
Test *pArray[3] = {new Test(4),new Test(1,2)};
注意:
- 對象數(shù)組初始化滩届,每個數(shù)組中的對象都會調(diào)用構(gòu)造函數(shù)集侯。
- 指針數(shù)組初始化被啼,只有創(chuàng)建過對象的位置的指針會被賦值,否則指針會為 NULL棠枉。
- new 創(chuàng)建的對象在堆內(nèi)存上浓体,可以通過指針在不同對象和函數(shù)之間傳遞,而函數(shù)中聲明的對象是在棧內(nèi)存上創(chuàng)建的辈讶,要想在作用域外使用必須復(fù)制(包括返回值也是賦值)命浴,因?yàn)樽饔糜蛞坏┙Y(jié)束,棧內(nèi)存上的對象都析構(gòu)了贱除。而堆內(nèi)存上的對象都要手動刪除(除非用智能指針)生闲,而且手動刪除前對象是保證可以被任何擁有該指針的函數(shù)訪問的。另外堆內(nèi)存的可用空間比棧內(nèi)存大的多月幌。