我們可以想象一個這樣的場景:某一天書店整理庫存,發現了一些非常老的書,為了盡快清空庫存,店主想了一下,決定開展一個大甩賣活動,所有的這些書全部以五美元的價格出售。此時如果需要盡快將這些書的信息錄入到書店的書單中,為了方便,我們可以在book類中添加一個帶默認參數的構造函數。
#include<iostream> using namespace std; class book { public: book(){} book(char* a, double p = 5.0); void display(); private: double price; char * title; }; book::book(char* a, double p) //在定義函數的時候可以不指定默認參數 { title = a; price = p; } void book::display() { cout<<"The price of "<<title<<" is $"<<price<<endl; } int main() { book Harry("Harry Potter", 49.9); Harry.display(); book Gone("Gone with the Wind"); Gone.display(); return 0; }
在本例中,book類中的帶參構造函數 book(char* a, double p = 5.0); 將價格設置為5.0,如此一來p就被設置成為一個默認參數,如果在創建對象的時候,沒有傳遞實參給該參數p,則該參數會被默認設置為5.0。
在例1的主函數中我們可以看到Harry對象創建時傳遞了兩個實參"Harry potter"和49.9,而Gone 對象則只是傳遞了一個實參"Gone with the Wind"用於初始化title,此時price就會被用默認參數初始化為5.0。
程序運行結果如下:
The price of Harry Potter is $49.9
The price of Gone with the Wind is $5.0
需要說明的是帶默認參數的構造函數,其默認參數必須置於參數列表的結尾。如果例1中帶參構造函數 book(char* a, double p = 5.0); 被聲明成 book(double p = 5.0, char* a); 則是無法通過編譯的,因為默認參數不在參數列表的結尾。
默認帶參構造函數所帶來的歧義:
#include<iostream>
using namespace std;
class book
{
public:
book(){}
book(char* a, double p = 5.0);
book(char *a);
void setprice(double a);
double getprice();
void settitle(char* a);
char * gettitle();
void display();
private:
double price;
char * title;
};
book::book(char* a, double p) //在定義函數的時候可以不指定默認參數
{
title = a;
price = p;
}
book::book(char *a)
{
title = a;
}
void book::display()
{
cout<<"The price of "<<title<<" is $"<<price<<endl;
}
int main()
{
book Harry("Harry potter", 49.9);
Harry.display();
book Gone("Gone with the Wind"); //compile error
Gone.display();
return 0;
}
在本例中有三個構造函數,一個是默認構造函數,兩個帶參構造函數,其中一個為帶有默認參數的構造函數。
在主函數中,通過book類創建Harry對象沒有問題,此時創建對象只能調用book(char* a, double p = 5.0);構造函數。創建Gone對象時則有問題了,此時我們創建對象有兩個與之匹配的構造函數可以調用,分別是book(char *a);和book(char* a, double p = 5.0);,此時該調用哪一個呢?無法得知,編譯器只能報錯了。
出現這種情況我們只能極力去避免了,通常而言,在設計類的構造函數的時候最好不要同時是用構造函數的重載和帶參數的構造函數,以避免上述問題。
