[英]C++: Constructor ambiguity
这会引起歧义吗?:
class A { ... };
class B : public A {
//...
B(const B& b);
B(const A& a);
//...
};
更新:询问者似乎已经从问题中清除了类名。 这是为此答案编写的原始代码:
class Vector2D { ... };
class Vector3D : public Vector2D {
//...
Vector3D(const Vector2D& b);
Vector3D(const Vector3D& a);
//...
};
我刚才说“不”,但是我改变了主意。 这是模棱两可的,我想不出让Vector3D
从Vector2D
继承的充分理由。
从数学角度看,可以将2D向量空间扩展为3D向量空间,但是有很多扩展可供选择-它们不是唯一的。 因此,当您创建从2D矢量类继承的3D矢量类时,您会将2D空间在3D空间中的一个嵌入“特权化”,而所有其他嵌入都变得次等。 我认为这不是特别有用。
您正在做的另一件事是说“每个3D矢量都是2D矢量”,这有点愚蠢。 例如,也许您编写了一个函数:
// Compute the angle between two vectors
double angle(Vector2D x, Vector2D y);
假设您忘记编写3D向量的版本。 现在,编译器将无法向您显示错误消息:相反,将使用在创建类时选择的“特权”投影将3D向量投影到2D空间中,并且会得到错误的答案。 现在假设您添加了另一个功能:
// Compute the angle between two 3D vectors
double angle(Vector3D x, Vector3D y);
现在,仍然有问题。
Vector3D x = ...;
Vector2D y = ...;
double a = angle(x, y);
这将使用x的2D投影,同样,您不会收到编译器警告。 您只会得到错误的答案。
简介:这是最糟糕的歧义:编译器会为您提供意料之外的答案。
Vector3D不应继承Vector2D。 这在数学上是不合逻辑的。
在选择引用基类和派生类型的重载构造函数之间进行选择时,通常不会产生歧义。
如果参数是从基本类型( A
)派生的类型,而不是从派生类型( B
)派生的类型,或者从派生类型派生的类型,则显然只有引用base的构造函数才是匹配项。
如果参数是派生类型,则在调用引用了派生类型的构造函数仅需要进行身份转换的点上,调用采用基类的构造函数所需的转换就需要派生为基类型。后者是更好的搭配。
如果该参数是从所述派生类型(派生的类的B
),则构造服用派生类型( B
)仍然是一个更好的匹配,因为标准说,结合到派生类型的参考比结合到参考更好该类型的碱基。 (ISO / IEC 14882:2011 13.3.3.2/4-对隐式转换序列进行排名[over.ics.rank])
显然,如果您努力尝试,仍然会产生歧义。
例如
struct S {
operator A() const;
operator B() const;
};
S s;
B b(s);
运算符&
生成参考。
在您的情况下,第一种类型是对Vector3D类型的引用,另一种类型是对Vector2D类型的引用,因此它们是不同的类型。
由于它们是不同的类型,它们将使构造函数的签名不同,并且也不会产生歧义。
答案是不。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.