39

子クラスが親クラスの特定のメソッドをオーバーライドするのを防ぐための C++ の言語機能または手法を知っている人はいますか?

class Base {
public:
    bool someGuaranteedResult() { return true; }
};

class Child : public Base {
public:
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};

仮想ではありませんが、これはまだ許可されています (少なくとも私が使用している Metrowerks コンパイラでは)。非仮想継承関数 X を非表示にすることに関するコンパイル時の警告だけが表示されます。

4

14 に答える 14

15

いくつかのアイデア:

  1. 関数を非公開にします。
  2. 関数を仮想化しないでください。ただし、これは実際には、関数が別の定義によって隠されることを妨げません。

それ以外には、関数がオーバーロードされないようにして、子クラスへのポインター/参照を介して呼び出すことができるように関数をロックする言語機能を認識していません。

幸運を!

于 2008-08-20T06:53:40.533 に答える
8

あなたが探しているものは、メソッドがサブクラスによってオーバーライドされるのを防ぐJava言語のfinalキーワードに相当するように聞こえます。

ここでの人が示唆しているように、あなたは本当にこれを防ぐことはできません。また、これはかなりよくある質問のようです。

于 2008-08-20T07:45:10.393 に答える
3

(a) 関数をプライベートにすることは解決策ではないと思います。これは、基本クラスの関数を派生クラスから隠すだけだからです。派生クラスは、常に同じシグネチャを持つ新しい関数を定義できます。(b) 関数を非仮想にすることも完全な解決策ではありません。派生クラスが同じ関数を再定義する場合、コンパイル時のバインディング、つまり obj.someFunction() によっていつでも派生クラス関数を呼び出すことができるためです。ここで、obj はのインスタンスです派生クラス。

これを行う方法があるとは思いません。また、派生クラスが基本クラス関数をオーバーライドすることを禁止した理由を知りたいです。

于 2008-09-23T12:02:39.933 に答える
2

コンパイラが警告しているのは隠れていると思います!! 実際にオーバーライドされていますか?

コンパイラは警告を出すかもしれませんが、実行時に、ポインターが指すオブジェクトの実際の型に関係なく、ポインターが親クラスの型である場合、親クラスのメソッドが呼び出されます。

これは面白い。コンパイラ用の小さなスタンドアロン テスト プログラムを作成してみてください。

于 2008-09-23T13:13:01.747 に答える
2

非仮想継承関数 X の非表示に関するコンパイル時の警告。

コンパイラの設定を変更して、警告ではなくエラーにします。

于 2008-08-20T06:55:12.573 に答える
1

明確にするために、あなたのほとんどは彼の質問を誤解しました。彼はメソッドを「オーバーライド」することについて質問しているのではなく、「非表示」を防ぐ方法があるかどうかを質問しています。そして、簡単な答えは「何もない!」ということです。

これが彼の例です

親クラスは関数を定義します:

int foo() { return 1; }

親を継承する子クラスは、同じ関数AGAINを定義します(オーバーライドしない):

int foo() { return 2; }

これは、すべてのプログラミング言語で実行できます。このコードのコンパイルを妨げるものは何もありません(コンパイラーの設定を除く)。あなたが得る最良のものは、あなたが親のメソッドを隠しているという警告です。子クラスを呼び出してfooメソッドを呼び出すと、2が得られます。コードは実質的に壊れています。

これが彼が求めていることです。

于 2009-10-13T18:09:02.203 に答える
0

サブクラスで関数と同じ名前を誰かが使用できないようにすることは、リンクされたライブラリで宣言したものと同じグローバル関数名を誰かが使用できないようにすることと大差ありません。

他のユーザーではなくあなたのコードを使用することを意図しているユーザーが、コードを参照する方法に注意し、正しいポインター型を使用するか、完全修飾スコープを使用することを期待するだけです。

于 2008-08-21T01:27:11.807 に答える
0

子クラスをその親の型として扱う場合、非仮想関数は親クラスのバージョンを呼び出します。

すなわち:

Parent* obj = new Child();
于 2008-08-20T06:53:36.647 に答える
0

メソッドを virtual にしない限り、子クラスはそれをオーバーライドできません。子クラスから呼び出されないようにする場合は、プライベートにします。

したがって、デフォルトでは、C++ は必要なことを行います。

于 2008-08-20T06:57:47.247 に答える
0

あなたの例では、関数はオーバーライドされません。代わりに隠されています(オーバーロードの一種の退化したケースです)。エラーは Child クラス コードにあります。csmba が提案したように、できることはコンパイラの設定を変更することだけです (可能な場合)。独自の機能を隠しているサードパーティのライブラリを使用しない限り、問題ありません。

于 2008-09-23T13:00:30.810 に答える
-1

私は同じものを探していましたが、昨日、この [かなり古い] 質問にたどり着きました。

今日、きちんとした C++11 キーワードを見つけました: final. 次の読者に役立つかもしれないと思いました。

http://en.cppreference.com/w/cpp/language/final

于 2016-08-04T06:00:41.170 に答える
-2

C++ メソッドは、デフォルトではプライベートであり、オーバーライドできません。

  • プライベート メソッドをオーバーライドすることはできません
  • virtual非メソッドをオーバーライドすることはできません

おそらく過負荷について言及していますか?

于 2008-08-20T06:54:28.097 に答える