構(gòu)造函數(shù)
函數(shù)名必須和類名完全相同,沒有返回類型,當(dāng)對象被創(chuàng)建時有系統(tǒng)自動調(diào)用殉疼,設(shè)置對象的初始狀態(tài)瓢娜。
- C++規(guī)定,每個類必須有默認(rèn)的構(gòu)造函數(shù)眠砾,沒有構(gòu)造函數(shù)就不能創(chuàng)建對象。
- 若沒有提供任何構(gòu)造函數(shù)褒颈,那么c++提供自動提供一個默認(rèn)的構(gòu)造函數(shù),該默認(rèn)構(gòu)造函數(shù)是一個沒有參數(shù)的構(gòu)造函數(shù)堡掏,它僅僅負(fù)責(zé)創(chuàng)建對象而不做任何賦值操作刨疼。
- 只要類中提供了任意一個構(gòu)造函數(shù),那么c++就不在自動提供默認(rèn)構(gòu)造函數(shù)游两。
- 類對象的定義和變量的定義類似漩绵,使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建對象的時候,如果創(chuàng)建的是靜態(tài)或者是全局對象宝踪,則對象的位模式全部為0碍扔,否則將會是隨機(jī)的。
默認(rèn)構(gòu)造函數(shù)(缺省構(gòu)造函數(shù))
可以不帶任何參數(shù)構(gòu)造對象厉膀,表示對象默認(rèn)(缺省)狀態(tài)。如果有參構(gòu)造函數(shù)的所有參數(shù)都帶有默認(rèn)值凳兵,那么該構(gòu)造函數(shù)就也可以被當(dāng)做默認(rèn)構(gòu)造函數(shù)企软。
默認(rèn)構(gòu)造函數(shù)(缺省構(gòu)造函數(shù))跟系統(tǒng)提供不提供構(gòu)造函數(shù)沒有任何關(guān)系,默認(rèn)構(gòu)造函數(shù)就是當(dāng)你定義一個對象時不需要提供初始化的的構(gòu)造函數(shù)形庭。
包括三種情況:
- 根本沒有顯式的定義構(gòu)造函數(shù)厌漂,當(dāng)然由系統(tǒng)提供的默認(rèn)構(gòu)造函數(shù),這個構(gòu)造函數(shù)沒有參數(shù)验靡,啥也不做
- 定義了構(gòu)造函數(shù)雏节,但是不帶任何參數(shù)高职,這也叫默認(rèn)構(gòu)造函數(shù),特別的寥粹,如果這個函數(shù)體什么都不執(zhí)行埃元,就跟情況1一樣。
- 定義了構(gòu)造函數(shù)阔拳,也帶有參數(shù)类嗤,但是所有參數(shù)都有默認(rèn)參數(shù),這個也叫默認(rèn)構(gòu)造函數(shù)货裹。
A default constructor is a constructor which can be called with no arguments (either defined with an empty parameter list, or with default arguments provided for every parameter). A type with a public default constructor is DefaultConstructible.
來源:http://en.cppreference.com/w/cpp/language/default_constructor
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默認(rèn)構(gòu)造函數(shù)
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
};
轉(zhuǎn)換構(gòu)造函數(shù)
可以通過單個參數(shù)調(diào)用的構(gòu)造函數(shù)精偿,從參數(shù)的類型隱式轉(zhuǎn)換為所構(gòu)造對象的類型赋兵。通過explicit關(guān)鍵字可以強(qiáng)制通過這樣的構(gòu)造函數(shù)所進(jìn)行的類型轉(zhuǎn)換必須顯式完成霹期。
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默認(rèn)構(gòu)造函數(shù)
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//帶參構(gòu)造函數(shù)
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//類型轉(zhuǎn)換構(gòu)造函數(shù)斯撮,根據(jù)一個指定的類型的對象創(chuàng)建一個本類的對象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
};
拷貝構(gòu)造函數(shù)(復(fù)制構(gòu)造函數(shù))
以所構(gòu)造對象類型的(常)引用為唯一調(diào)用參數(shù)的構(gòu)造函數(shù)勿锅,實現(xiàn)同類型對象的克隆,即構(gòu)造對象的副本溢十。
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默認(rèn)構(gòu)造函數(shù)
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//帶參構(gòu)造函數(shù)
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//類型轉(zhuǎn)換構(gòu)造函數(shù)张弛,根據(jù)一個指定的類型的對象創(chuàng)建一個本類的對象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
//拷貝構(gòu)造函數(shù)
Student (Student const& that)
{
m_id = that.m_id;
m_name[20] = that.m_name[20];
m_age = that.m_age;
}
};
析構(gòu)函數(shù)
析構(gòu)函數(shù)在對象被銷毀時自動調(diào)用。對于局部對象而言寺董,就是在它離開作用域時刻剥,對于堆對象而言,delete/delete[]負(fù)責(zé)調(diào)用析構(gòu)函數(shù)御吞。析構(gòu)函數(shù)通常負(fù)責(zé)在對象被銷毀之前漓藕,釋放其動態(tài)分配的資源。
析構(gòu)函數(shù)不能重載揍诽。
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默認(rèn)構(gòu)造函數(shù)
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//帶參構(gòu)造函數(shù)
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//類型轉(zhuǎn)換構(gòu)造函數(shù)嫩与,根據(jù)一個指定的類型的對象創(chuàng)建一個本類的對象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
//拷貝構(gòu)造函數(shù)
Student (Student const& that)
{
m_id = that.m_id;
m_name[20] = that.m_name[20];
m_age = that.m_age;
}
//析構(gòu)函數(shù)
~Student (void)
{
//這里不能這樣寫划滋,C++中內(nèi)置類型不需要delete/delete[]
//delete m_id, m_name[20], m_age; //error
cout << "~這是析構(gòu)函數(shù)~" << endl;
}
};
構(gòu)造和析構(gòu)的順序:
當(dāng)一個對象被構(gòu)造時,先執(zhí)行成員子對象的構(gòu)造函數(shù)处坪,后執(zhí)行該對象的構(gòu)造代碼。如果函數(shù)多個成員子對象玄帕,按照其被聲明的順序依次構(gòu)造。析構(gòu)的順序和構(gòu)造嚴(yán)格相反委刘。
最后奉上程序完整代碼:
#include <iostream>
using namespace std;
class Student
{
private:
int m_id; string m_name[20]; int m_age;
public:
//默認(rèn)構(gòu)造函數(shù)
Student (void)
{
m_id = 0;
m_name[20] = {0};
m_age = 0;
}
//帶參構(gòu)造函數(shù)
Student (int id, char name[20], int age)
{
m_id = id;
m_name[20] = name[20];
m_age = age;
}
//類型轉(zhuǎn)換構(gòu)造函數(shù)锡移,根據(jù)一個指定的類型的對象創(chuàng)建一個本類的對象
//int->Student
explicit Student (int id)
{
m_id = id;
m_name[20] = {0};
m_age = 0;
}
//拷貝構(gòu)造函數(shù)
Student (Student const& that)
{
m_id = that.m_id;
m_name[20] = that.m_name[20];
m_age = that.m_age;
}
//析構(gòu)函數(shù)
~Student (void)
{
//這里不能這樣寫漆际,C++中內(nèi)置類型不需要delete/delete[]
//delete m_id, m_name[20], m_age; //error
cout << "~這是析構(gòu)函數(shù)~" << endl;
}
void show(void)
{
cout << "學(xué)號:" << m_id << "\t" << "姓名:" << m_name << "\t" << "年齡:" << m_age << endl;
}
};
int main(int argc, const char * argv[]) {
Student stu1 (1001, "王二", 17);
stu1.show();
Student stu2 (1002, "大許", 17);
stu2.show();
Student stu3 (1003, "邢紅", 16);
stu3.show();
return 0;
}