2013-06-18 149 views
7

到目前为止,我知道,如果你想传递一个默认值的参数传递给函数是一个对象,你做这样的:默认对象值的值

void function(MyObject obj = MyObject()){ 
    ... 
} 

然而,最近我发现了一些有趣的语法,这让我很困惑。 当我们调用这个函数时会发生什么?

void function(MyObject obj = 0){ 
    ... 
} 

请注意,我们正在传递一个对象,而不是指针。上面的代码编译得很好,没有错误或警告。而这总是一个参数调用构造 - MyObject的定义是这样的:

class MyObject{ 
public: 
    MyObject(double n){std::cout << "Argumented\n";} 
    MyObject(){std::cout << "Default\n";} 
}; 

此外,其中这种行为记录(因为我搜索,但没有找到它)?

+1

C++标准第4章(标准转换)和第12.3章(特殊成员函数/转换)。还有13.3.3.1(隐式协方差序列)。 – jrok

+0

@jrok非常感谢。 –

+0

不客气。这些章节编号来自n3337草案,但我希望它们在官方(C++ 11)标准中是相同的。 – jrok

回答

11

通过调用MyObject(double)构造函数,该参数默认为从0隐含构造的MyObject。此构造函数允许隐式实例化MyObjects这样的:

MyObject o1 = 0; 
MyObject o2 = 420/10.; 

如果这种行为是不打算,然后再进行构造explicit。这也将需要改变function的默认参数:

explicit MyObject(double n); 

void function(MyObject obj = MyObject(0)); 
+1

此外,如果你想禁用这种行为,你可以标记你的构造函数为'显式' – WaelJ

+0

噢,为什么我之前没有想到这一点?谢谢。 –

5

为MyObject如图所示,从双有一个所谓的implicit converting constructor。由于0对于double来说可以,所以你看到的效果就像你做的MyObject(0.0)。

4

假设下面的表达式:

MyObject obj = 0; 

编译并具有MyObject类型的值,则函数调用服用MyObject将能够以相同的方式工作。

设想这样的函数签名:

void function(MyObject obj){ 
    ... 
} 

和以下呼叫者的代码:

MyObject obj = 0; 
function(obj); 

这等同于该第二呼叫者的代码:

function(MyObject obj = 0); 

由于MyObject obj = 0;值等于已经构建的MyObject在那行代码中编辑。

您只是向前迈进了一步,并通过利用相同规则提供默认参数值。