0

これはあいまいさを引き起こしますか?:

class A { ... };
class B : public A {
//...
B(const B& b);
B(const A& a);
//...
};
4

3 に答える 3

4

更新:質問者が質問からクラス名を削除したようです。この回答が書かれている元のコードは次のとおりです。

class Vector2D { ... };
class Vector3D : public Vector2D {
//...
Vector3D(const Vector2D& b);
Vector3D(const Vector3D& a);
//...
};

先ほど「ノー」と言いましたが、気が変わりました。Vector3Dこれはあいまいであり、から継承する正当な理由は考えられませんVector2D

数学的な観点からは、2Dベクトル空間を3Dベクトル空間に拡張できますが、選択できる拡張機能は多数あります。これらは一意ではありません。したがって、2Dベクトルクラスから継承する3Dベクトルクラスを作成すると、3D空間への2D空間の埋め込みが「特権」になり、他のすべての埋め込みが劣ります。それは特に便利ではないと思います。

あなたがしているもう一つのことは、「すべての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から継承しないでください。それは数学的に非論理的です。

于 2012-07-28T21:38:24.210 に答える
2

ベースと派生型への参照をとるオーバーロードされたコンストラクターから選択する場合、通常、あいまいさはありません。

パラメーターが基本型(A)から派生した型であるが、派生型(B)から派生した型ではない場合、または派生型から派生した型である場合、明らかに、基本への参照を取得するコンストラクターのみが一致します。

パラメーターが派生型の場合、基本クラスを取得するコンストラクターを呼び出すために必要な変換には、派生型への参照を取得するコンストラクターへの呼び出しでID変換のみが必要な時点で、派生型から基本型への変換が必要です。後者の方が適しています。

If the parameter is of a class derived from the derived type (B) then the constructor taking the derived type (B) is still a better match because the standard says that binding to a reference of a derived type is better than binding to a reference of a base of that type. (ISO/IEC 14882:2011 13.3.3.2 / 4 - Ranking implicit conversion sequences [over.ics.rank])

Obviously you can still generate ambiguities if you try hard enough.

E.g.

struct S {
    operator A() const;
    operator B() const;
};

S s;
B b(s);
于 2012-07-28T23:00:42.777 に答える
1

オペレーター&は参照を生成します。

あなたの場合、最初のタイプはVector3Dタイプへの参照であり、もう1つはVector2Dタイプへの参照であるため、これらは異なるタイプです。

これらはタイプが異なるため、コンストラクターのシグネチャが異なり、あいまいさも発生しません。

答えはいいえだ。

于 2012-07-28T21:31:39.553 に答える