我正在审查我的决赛,我无法弄清楚为什么这个问题是什么。
假设以下类声明:
class Testing {
public:
Testing(int n);
void Show(const Testing& w, int a = 10);
int value;
private:
int DoThis();
};
假设以下几行代码正在main()程序中尝试,并且x的类型为Testing
,并且已经在属性上创建。
x.Show(18);
合法或非法
答案是合法的,我理解由于= 10
而不需要第二个参数,但由于18
不是Testing
类型,这不是一个无效的参数吗?
答案 0 :(得分:16)
测试有一个非explicit
构造函数,它接受一个int。因此,可以通过构造临时对象将int隐式转换为Testing
。
由于Show需要const Testing &
(而不仅仅是Testing &
),因此您可以将临时值传递给它。最后,第二个参数是可选的,因此您不必为此指定值。
顺便说一下,整个机制允许你这样做:
void f(const std::string &str);
// ...
f("Hello");
此处,"Hello"
属于const char (&)[6]
类型,可以衰减为const char *
,但您可以从std::string
构建const char *
,从而允许使用const char *
,其中需要std::string
参数。
请记住,这构造了一个临时的,因此仅对通过值或const引用传递的参数有效(对于引用将失败)。此外,不能将构造函数标记为explicit
。
答案 1 :(得分:6)
C ++中有一种自动转换的概念,称为implicit conversion sequences。在这样的序列中,最多一次转换可以是用户定义的转换,并且为临时对象调用构造函数是用户定义的转换。可以在这里创建一个临时的,因为它将绑定到const-reference,并在Show()调用完成时被销毁。
答案 2 :(得分:5)
由于Testing
具有接受int
的构造函数,因此该c-tor用于为第一个参数自动构造Testing
对象。代码实际上最终会起作用:
x.Show(Testing(18));
答案 3 :(得分:3)
这里的构造函数:
Testing(int n);
提供从int
到Testing
的隐式转换,然后匹配Show
的原型,第一个参数是Testing
实例,由{int
构成1}} 18,第二个参数是默认值10.
如果您阻止隐式转换,请执行以下操作:
explicit Testing(int n);
代码无法编译。