C++中有6個默認的成員函數,在類中未實現的成員函數編譯器將默認生成該成員函數。
class Good
{
public:
Good(char* name= NULL,float price = 0);//默認構造函數
~Good();//析構函數
Good(const Good &);//拷貝構造函數
Good& operator =(const Good& g);//賦值運算符
Good* operator &();//取址運算符
const Good* operator &()const;
private:
char* name;
float price;
};
構造函數
構造函數是一種特殊的成員函數,在實例化的過程中被調用,只執行一次並且沒有this指針。
默認構造函數通常是指無參的構造函數,函數體爲空,不執行任何操作,在類內沒有任何構造函數時編譯器將會默認生成的無參構造函數。
Good::Good()
{
name = new char[1];
}
一旦定義了構造函數,則編譯器不會在生成默認構造函數。如果需要對對象初始化是可以採用缺省的構造函數和使用初始化參數表兩種初始化方式。
Good::Good(char* mname = "",float mprice = 0)
{
if(name != NULL)//strlen 函數不能接受參數 NULL
{
name = new char[strlen(mname)+1]();
strcpy(name,mname);
price = mprice;
}
name = new char[1]();
price = 0;
}
Good::Good(char* mname ): price(0);
初始化列表可以對const修飾的變量或者引用等變量進行初始化。
拷貝構造函數
Good::Good(const Good & g)//只能引用,否則循環調用拷貝構造函數,無窮遞歸
{
name = new char[strlen(g.name)+1]();//防止淺拷貝,重複析構
strcpy(name,g.name);
price = g.price;
}
賦值運算符重載
Good& Good::operator =(const Good& g)//形參可以使用Good類型,但是使用引用可以提高效率,減少臨時對象的生成
{
if(g == this)//排除自賦值的情況
{
return;
}
delete[] name;//釋放之前佔用的資源
name = new char[strlen(g.name)+1]();//開闢新資源
strcpy(name,g.name);
price = g.price;
}
賦值運算符重載函數需要考慮:1.是否爲自賦值;2.釋放佔有的舊資源;3.開闢新資源。//this 指針爲 Good *const
Good G;
G = "AK";//編譯器檢查類型不相同,生成臨時對象
臨時對象的生存週期爲一個語句結束,但explicit關鍵字禁止隱式轉換。析構函數
析構函數用來釋放被佔用的資源比如釋放申請的內存、關閉打開的文件;一個類中只用一個析構函數,不能重載;對象聲明週期結束時,系統自動調用析構函數。
Good::~Good()
{
delete []name;//使用數組的析構方式
}
因爲函數壓棧的關係,調用構造函數和析構函數的順序,先構造的後析構,後構造的先析構。
取地址運算符重載
取地址運算符一般不需要重新定義。
const Good* operator &()const
{
return this;
}
前一個const表示返回類型爲常對象的指針,後一個const表示常成員函數、只能常成員對象調用,
//this :const Good *const
只能訪問變量不能修改變量,使用Mutable關鍵字的變量可以被修改。
static函數
static void Good::ShowCname()
{
cout << "Good"<<endl;
}
static函數屬於類不屬於對象,沒有this指針,不依賴對象調用。
Good::ShowCname();
static變量在類外初始化。
參考資料:
詳解c++中類的六個默認的成員函數 - CSDN博客 http://blog.csdn.net/peiyao456/article/details/51834981