6

例:

class C
{
  public:
    void operator =(int i) {}
};

class SubC : public C
{
};

以下はコンパイルエラーになります:

SubC subC;
subC = 0;

「'subC = 0' の 'operator=' に一致しません」

一部の情報源は、代入演算子が継承されていないためであると述べています。しかし、それは単純に、デフォルトで構築されたコピー代入がSubCそれらを覆い隠しているからではありませんか?

4

4 に答える 4

11

コピー代入演算子は、派生クラスで自動的に生成されます。これにより、C++ の通常の名前非表示規則により、基本クラスの代入演算子が非表示になります。「using」ディレクティブを使用して、基本クラスの名前を再表示できます。例えば:

class C
{
  public:
    void operator =(int i) {}
};

class SubC : public C
{
  public:
    using C::operator=;
};
于 2012-04-09T00:31:02.387 に答える
2

基本クラスのコピー代入演算子に、派生クラスのコピー代入演算子に必要な署名がありません。これは派生クラスによって継承されますが、コピー代入演算子を構成しません。そのため、代入演算子は継承されますが、他のメンバー関数と同様に、コピー代入は提供されません。

于 2012-04-09T00:27:52.763 に答える
1

私はそれをしていませんが、The Man Himself (Stroustrup) によると、コンストラクターでそれを行うのは C++11 の機能ですが、他のメソッドで行うのは C++98 以降です。

これはリンクから直接持ち上げられます:

通常のスコープ ルールがクラス メンバーに適用されるという事実について、人々は混乱することがあります。特に、基本クラスのメンバーは、派生クラスのメンバーと同じスコープにはありません。

struct B {
    void f(double);
};

struct D : B {
    void f(int);
};

B b;   b.f(4.5);  // fine
D d;   d.f(4.5);  // surprise: calls f(int) with argument 4

C++98 では、オーバーロードされた関数のセットを基本クラスから派生クラスに「持ち上げる」ことができます。

struct B {
    void f(double);
};

struct D : B {
    using B::f;     // bring all f()s from B into scope
    void f(int);    // add a new f()
};

B b;   b.f(4.5);  // fine
D d;   d.f(4.5);  // fine: calls D::f(double) which is B::f(double)

では、どうぞ。私自身はまだ試していませんが、C++11 より前であっても、おそらく「必要に応じて使用する」ことができます。

于 2012-04-09T00:36:02.743 に答える
0

コピー代入演算子を除いて、他のオーバーロードされた演算子を継承できます。

私は、SubCのデフォルトで構築されたコピー代入がCのオーバーロードされた代入演算子を覆い隠すという意見に同意します。

SubCがコピー代入演算子を提供しない場合、コンパイラは次のようにコピー代入演算を合成します。

class SubC : public C
{ 
public:
    SubC & operator=( const SubC & other );
}

その場合、「SubC&operator =(const SubC&other)」はCの代入演算子を覆い隠し、コンパイルエラーが発生します。

もしも

SubC other;
SubC subC;

subC = other;

次に、この場合、正常にコンパイルします。

于 2012-04-09T01:00:25.753 に答える