3

我想完全理解转换,即确保我知道函数调用何时会导致隐式转换,以及何时会导致编译错误。我了解到,当且仅当有一种单一的方法可以通过以下列表中的最多两个步骤(按优先级排序)转换变量时才可以进行转换:

1. Exact match
2. Promotion
3. Conversion
4. User defined conversion

我理解的方式(你可以纠正我)是提升是将基元转换为更大的基元类型,例如 short 到 int、float 到 double 等;转换是非提升的基元之间的任何转换,例如 int 到 char 等;用户定义的转换是使用转换构造函数和转换运算符对类进行的转换。现在,我也知道继承意味着和 Is-A 关系,这意味着派生类是基类,因此将派生类发送到期望对基类的引用的函数应该可以工作。结合上面的两个概念,我们应该知道我写的下面的例子应该可以工作:

class C {};
class D: public C
{
public:
D(int x){}
};
void f(C& c) {}
f(3);

因为 D 可以从 int 转换为,并且 D 是 C。但是这段代码没有被编译。这是为什么?矛盾如何化解?你能解释一下这件事吗?谢谢!

4

1 回答 1

5

代码无法编译,因为转换会创建一个临时的,它不能绑定到非const引用。

如果您通过const引用(或按值,但我不建议您这样做)传递参数,它将起作用。

您还需要基类中的转换构造函数(如下所述)。

class C {
public:
   C(int x){}
};
class D: public C
{
public:
   D(int x):C(x){}
};

void f(const C& c) {}
f(3);

这是因为隐式转换最多只应用一次。在您的情况下,有一个 fromint -> D和一个 from的直接转换D -> C,因此 anint不能隐式转换为C.

于 2012-06-26T08:34:36.627 回答