2010-01-16 55 views
4

我想這是一個非常荒謬的/基本的問題,但仍:C++ ......當所有的參數都有默認值

class m 
{ 
public: 
    void f(int ***); 
    /***/ 
} 
void m::f(int ***a = NULL) 
{ 
    /***/ 
} 

的F的調用(以及它有默認值的任何功能對於全部參數)不接受0個參數。爲什麼?那麼我應該如何格式化聲明呢?

回答

13

,如果函數定義是在頭文件中正常工作。規則是任何正在調用函數的人都必須「看見」默認值。

所以,我猜你在一個單獨的源文件中的函數定義。假如是這樣的話,只要把函數聲明默認值(在類):

class m 
{ 
public: 
    void f(int *** = 0); 
    /***/ 
}; 

您還需要從函數定義刪除默認值,你可以只在一個單一的定義默認地方(即使價值本身是相同的)。

+0

噢。相同的文件,但呼叫在定義之前。很容易猜到爲什麼!雖然我有虛構的感覺(當然是基於隨機性),但問題與具有默認值的所有參數的函數有關。 乾杯! – huff 2010-01-16 06:37:04

2

這將工作:在C++是語法糖

class m 
{ 
public: 
    void f(int ***a = NULL); 
}; 

void m::f(int ***a) 
{ 
} 
2

的默認值;編譯器在調用網站上爲你插入參數。這意味着編譯器需要知道默認值是什麼,所以它必須由函數聲明提供。

這也意味着,如果你有繼承和虛方法,使用默認值是從靜態類型的那些(即,什麼類型的編譯器認爲對象),而不是從運行時類型。例如:

class Base 
{ 
public: 
    virtual ~Base() { } 

    virtual std::string foo(std::string s = "b") { return "Base:" + s; } 
}; 

class Derived 
: public Base 
{ 
public: 
    virtual std::string foo(std::string s = "d") { return "Derived:" + s; } 
}; 

int main(void) 
{ 
    Derived d; 
    Base& b = d; 
    std::cout << b.foo() << std::endl; 
    return 0; 
} 

將打印Derived:b,不Derived:d