1

以下は、派生クラスで基本メソッドを使用する方法の簡単な例です。

struct Base {
  void foo ();
  Base& operator = (const Base&);
};

struct Derived : Base {
  // ...
};

int main () {
  Derived d1, d2;
  d1.foo();  // calls Base::foo
  d1 = d2;   // calls Base::operator =
}

の本文に以下のステートメントを追加して、Derived両方のメソッドを非表示にすると、...

struct Derived : Base {
  //...
private: // hide the below method for `Derived` objects
  using Base::foo;
  using Base::operator =;
}

...その後、Base::foo()正常に非表示になります(アクセスできなくなります)。
それでもBase::operator =アクセス可能です!!

d1.foo(); // error
d1 = d2;  // ok !!

他の事業者でも同様の現象が起きています。これはg++ のデモです

アクセシビリティ規則 (usingキーワードによって適用される) は、メソッドと演算子に同じように適用されるべきではありませんか?
そうでない場合、ステートメントの意味は何ですか: using operator =;、コンパイラによって単に無視されますか?

更新

  1. 私の最初の考えは、コンパイラが独自のデフォルトを生成している可能性があるということでしたDerived::operator =。を使っているので間違い Base::operator =です。
  2. private継承を使用すると、Base::foo()自動的に非表示になります (なくてもusing)。しかし、影響はありませんBase::operator =。まだ機能しています。

「非表示にする方法」の解決策は望まないことに注意してください。しかし、言語の観点から、演算子が他のメソッドのように非表示にならない理由を理解したいと思います。

4

2 に答える 2

3

コンパイラはoperator=Derived クラスのデフォルトを生成し、これは暗黙的に内部的Derived::operator=に呼び出します。 これを取り除くには、明示的に無効にする必要があります。Base::operator=
operator=

struct Derived : Base {
  private: Derived& operator = (const Derived&);  // C++03 way
};

struct Derived : Base {
  Derived& operator = (const Derived&) = delete;  // C++11 way
};
于 2013-07-28T10:55:49.107 に答える
1

更新:
私が最初に考えたのは、コンパイラが独自のデフォルトの Derived::operator = を生成している可能性があるということでした。を使っているので間違いBase::operator =です。他のオペレーターについても同様です。

プライベート継承を使用すると、Base::foo()(使用しなくても) 自動的に非表示になります。しかし、影響はありませんBase::operator =。まだ機能しています。

あなたの最初は正しかった。コピー代入演算子を宣言しなかったため、暗黙的に宣言されました。次に、その暗黙的に宣言されたコピー代入演算子をodr使用したため、コンパイラは暗黙的に定義されたコピー代入演算子を提供しました。構造体またはクラスの暗黙的に定義されたコピー代入演算子は、クラスの基底クラスのメンバー単位のコピー代入を実行し、次に非静的データ メンバーです。

その暗黙的に定義されたコピー代入演算子は、クラス メンバーです。using基本クラスのコピー コンストラクターをプライベート継承またはプライベート継承を介して外の世界に隠していても、その基本クラスの代入演算子はこの暗黙的に定義されたコピー代入演算子から見えるため、少しも問題ではありません。

于 2013-07-28T11:25:01.513 に答える