0

次の C++ コードはコンパイルされません。

class BaseA {
protected:
    BaseA &operator = (const BaseA &rhs);
};

template<typename T>
class BaseB {
public:
    T &operator = (const T &rhs) {
        return *static_cast<T *>(this);
    };
};

class Derived :
    public BaseA,
    public BaseB<Derived> {
};

int main() {
    Derived foo;
    Derived bar;
    foo = bar;
    return 0;
};

これをコンパイルしようとすると、BaseA &BaseA::operator = (const BaseA &)未定義の苦情が表示されます。スタックオーバーフローにはこのような質問が他にもいくつかありますが、それらはすべて、Derived &Derived::operator = (const Derived &)を呼び出す関数を自動生成するコンパイラに関係しているようですBaseA::operator = (const BaseA&)。この場合、Derivedからその正確なシグネチャを持つ関数をすでに継承しているはずBaseB<Derived>です。別の質問のアドバイスに従って、オーバーロードできないというコンパイラの不平を追加using BaseB<Derived>::operator =;すると。DerivedDerived &operator = (const Derived &)

クラスがこの演算子を継承することは単に不可能ですか?

編集:明確にするために、コンパイラがすでにから継承しているのに、なぜDerivedデフォルトを与えるのか混乱しています。デフォルトのコピー代入演算子が通常作成され、継承された代入演算子をオーバーライドする理由を理解できますが、この場合、コピー代入演算子とまったく同じ署名を持つ演算子を継承しています。サブクラスがこの演算子を使用するように記述する方法はありますか?Derived &operator = (const Derived &)T &operator (const T &) where [T = Derived]Base<Derived>DerivedBaseB

4

3 に答える 3

5

いいえ、代入演算子operator=は継承されません。デフォルトはありません

Derived& operator=(const BaseA& a);

あなたの派生クラスで。

ただし、デフォルトの代入演算子が作成されます。

Derived& operator=(const Derived& a);

これは から代入演算子を呼び出しますBaseA。したがって、代入演算子を継承するのではなく、派生クラスで生成されたデフォルトの演算子を介して呼び出します。そしていくつかのメモ:標準は言う(12.8):

代入演算子は、厳密に 1 つのパラメーターを持つ非静的メンバー関数によって実装されます。ユーザーによって宣言されていない場合、コピー代入演算子 operator= はクラスに対して暗黙的に宣言されるため (12.8)、基本クラスの代入演算子は、派生クラスのコピー代入演算子によって常に隠されます。

次に、派生の代入演算子をベースに呼び出します

非共用体クラス X の暗黙的に定義されたコピー/移動代入演算子は、そのサブオブジェクトのメンバー単位のコピー/移動代入を実行します。X の直接の基底クラスは、base-specifier-list での宣言の順序で最初に割り当てられ、次に X の直接の非静的データ メンバーが、クラス定義で宣言された順序で割り当てられます。 .

于 2013-04-24T03:58:27.847 に答える
1

代入演算子は特別なメンバー関数の 1 つです。自分で提供しない場合、コンパイラは、ベースを割り当ててからメンバーを割り当てることによって生成します。ベースのいずれかに代入演算子がない場合は、代入演算子が生成されます。

あなたの問題は、 の代入演算子を宣言しましたBaseAが、定義を提供していないことです。宣言されているため、コンパイラは生成しませんが、それを呼び出してBaseAサブオブジェクトをコピーしようとします。リンカーは定義を見つけることができません。

割り当ての特定のケースでは、基本実装を継承しても意味がないことに注意してください。それが使用された場合、1 つのベースに代入演算子があるとすぐに、残りのオブジェクトは代入されません。ほとんどの場合、操作のセマンティクスは壊れます。

于 2013-04-24T04:12:28.343 に答える
0

基本クラスで宣言しない場合、基本クラスの演算子と他のすべてのメソッドを継承できます-宣言すると、デフォルトの代入演算子がコンパイラによって生成されます-独自の実装を提供する必要がある場合、エラーが発生しますoperator= が BaseA クラスで定義されておらず、宣言されているためです。

于 2013-04-24T03:57:27.573 に答える