2012-09-13 44 views
3

說我有下面的類:C++函數的參數創建類

class A 
{ 
public: 
    A() { 
    } 

    A(int a):_a(a){ 
    } 

    int _a; 
}; 

而下面的功能:

void someFunc (A a) 
{ 
    cout << a._a; 
} 

所以在程序中以下行正常工作:

someFunc (5); // Calls A(int a) Constructor. 

但以下不:

someFunc(); //Compile error 

可以預料到,如果它可以在獲取整數時構建A,那麼爲什麼不使用默認構造函數也可以構建一個?

+0

嘗試' void someFunc(A a = A())'如果你真的想要這樣的行爲。 – chris

回答

1

這是因爲someFunc()簽名不匹配的void someFunc (A a)

根據C++標準,第13.3.2.3:

  • 首先,是一種可行的功能,候選人功能應具有足夠的參數在該列表中的參數數目一致。
  • 具有比米參數的更多候選的功能是可行的只有當第(m + 1)-st參數都有一個默認參數

無這種適用於這種情況,所以void someFunc (A a)不被認爲可用的用於調用一個空的參數列表。

6

因爲someFunc()需要一個參數,你沒有提供它不會過載。存在從intA的隱式轉換,但這並不意味着您可以忽略該函數的簽名並且不帶任何參數地調用它。如果您想不帶任何參數地調用它,則將默認值分配給a

void someFunc(A a = A()) { 
    /* stuff */ 
} 
3

因爲你沒有打電話與竟然是轉換一個參數的函數,你無參數調用的函數。這是一個不同的超載,你沒有提供。

考慮這些選項:

  • 這樣調用該函數:someFunc(A())
  • 定義函數參數的默認值:void someFunc (A a = A()) { ... }
  • 提供沒有爭論過載:void someFunc() { someFunc(A()); }
0

Nitpick。從2003 C++標準中,

17.4.3.2.1全局名稱 - ... - 以下劃線開頭的每個名稱被保留到實現在全局命名空間

我會告訴你,作爲一個名稱,它的不良做法與_啓動任何變量名。特別是你可能會將這種做法擴展爲命名變量參數(int foo(int _a)),或者在不考慮的情況下使用camelcase(int _MyVar)。我個人不喜歡的東西

int a_; 

請問你是否真正有麻煩?可能不會。但最好不要用下劃線開始任何事情。從不在名稱的任何位置加兩個下劃線,或者從下劃線開始,後跟大寫字母,當然也是如此。

0

我並不是真的在這裏提供答案,但它是有用的信息都是一樣的......有時候你真的不想讓someFunc(5)工作,因爲它可能會導致不正確的操作,或者乾脆誤導人。在這種情況下,你可以聲明構造爲explicit

class A 
{ 
public: 
    A() {} // Are you sure you don't want to initialise _a here? 

    explicit A(int a) :_a(a) {} 

    int _a; 
}; 

正如其他人已經說過,你可以指定someFunc默認參數:

void someFunc(A a = A()); 

現在:

someFunc();  // Calls A() by default 

someFunc(5); // Not allowed because of implicit construction 

someFunc(A(5)); // Caller must pass an instance of A