繁体   English   中英

C ++:构造函数歧义

[英]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);
//...
};

我刚才说“不”,但是我改变了主意。 这是模棱两可的,我想不出让Vector3DVector2D继承的充分理由。

从数学角度看,可以将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM