私は、grand-parentクラスが関数XYZの純粋仮想バージョンを含む純粋仮想であるというコードを変更しています。その後、親クラスはXYSを仮想として宣言し、XYSを実装しています。次に、子クラスは、それ自体が私に混乱している親クラスの実装とは異なる実装で、XYZを通常の関数として宣言します。別のオブジェクトから関数XYZを呼び出すと、どの実装が実行されますか?親子か子供のどちらか?ありがとう純粋仮想と仮想の違い
答えて
純粋な仮想関数は(仮想関数ではなく)定義を必要とせず、クラスを抽象化します。抽象クラスは、基本クラスオブジェクトとして動作する場合を除いて、作成元のオブジェクトを持つことはできません。
あなたの混乱は、virtual
キーワードの有無を中心にしているようです。関数が基底クラスのvirtual
と宣言されている場合、virtual
キーワードを付けても、派生クラスの関数は、同じ名前、パラメータ型、および定数を持つ場合、自動的にvirtual
になります。
あなたが実際にchild
オブジェクトを指すgrandparent*
またはparent*
にXYZを呼び出すのであれば、その後、child
オブジェクトのXYZが実行されます。
私は自分の質問のタイトルが質問の内容とは無関係であることに気付きました。できれば私の質問の内容を読んで助けてください。ありがとうございました – user553514
@ user553514:Cheeky。彼はあなたの質問に答えました。 –
純粋仮想関数は、純粋仮想関数を持つクラスをインスタンス化できないことを意味します。親クラスがオーバーライドすると、それは通常の仮想関数になります。ファンクションが基本クラスで仮想宣言されると、継承クラスがそれを仮想として定義しているかどうかにかかわらず、常に仮想になります。
編集:これは、他の仮想関数と同じように仮想関数を呼び出すことです。つまり、最も派生したクラスの実装が呼び出されます。
+1は良い答えですが、これはOPが実際に尋ねた質問ではありません。混乱して、私は知っている... –
通常、純粋な仮想関数は実装がなく、クラスの「抽象度」を作成します。
コンパイラは抽象クラスのインスタンスを作成させません。継承するすべての純粋仮想関数が実装されていない限り、このクラスから派生したクラスは抽象クラスのままです(新しいクラスも追加されません)。そのようなクラスはコンクリートと呼ばれます。
純粋な仮想関数に実装を与えることができます(ただし、構文上の理由からインライン化することはできません)。さらに、純粋な仮想デストラクタを持つことができますし、空の仮想デストラクタを実装しなければなりません(空の場合でも)。
あなたは、このように末尾に= 0を追加することで、純粋仮想関数を示しています
virtual void foo(); // not pure
virtual void bar() = 0; // pure virtual
を私は実装が実行されます別のオブジェクトからXYZ関数を呼び出すときは?親子か子供のどちらか?
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { cout << "B::f\n"; }
};
struct C : B {
virtual void f() { cout << "C::f\n"; }
};
int main() {
C().f();
return 0;
}
class sample
{
public:
virtual void fun(); //virtual function
virtual void sun()=0; //pure virtual function
};
上記行われるように純粋仮想関数は、0
を割り当てることによって宣言されます。仮想関数の定義を提供することが、それ以外の場合はないコンパイルされ、強制ありながら純粋仮想関数の定義を提供することは、オプションです。また仮想関数を定義するクラスのインスタンスを作成することはできません。
仮想関数は、派生クラスでオーバーライドできる関数です。
純粋な仮想関数は実装が全くないため、MUSTは派生クラスでオーバーライドする必要があります。
純粋仮想関数を使用してクラスのインスタンスを作成することはできません。独自の実装で純粋仮想関数をオーバーライドしない限り、クラスのインスタンスを作成することはできません。仮想関数の場合
、あなたは子クラスのオブジェクトに対してXYZを呼び出す場合、XYZ(Child::xyz()
)の常に子のバージョンが実行されます。
非仮想オーバーライドされたメソッドの場合はありません。そしてポインタParent* ptr = &child
がある場合、ptr>xyz()
は実際にParent::xyz()
を実行します。しかしあなたの場合はChild::xyz()
です。そのため、virtual
というキーワードを使用しています。
- 1. 純粋仮想デストラクタ
- 2. デフォルト純粋仮想デストラクタ
- 3. C++ map.clear()純粋仮想メソッドランタイムエラー
- 4. 純粋仮想関数のオーバーロード
- 5. 仮想の有無にかかわらず純粋な仮想メソッドの実装?
- 6. C++:非仮想関数で純粋仮想関数を使用する
- 7. 仮想ボイドfuncFoo()const = 0と仮想ボイドfuncFoo()= 0の違い。
- 8. C++の純粋仮想関数の実装とヘッダファイル
- 9. 純粋な仮想関数のないC++抽象クラス?
- 10. C++ temporary - "純粋仮想メソッド"と呼ばれる
- 11. 保護されたコンストラクタと純粋な仮想デストラクタ
- 12. C++の純粋仮想メソッドのメモリ管理の問題
- 13. Webサイトと仮想ディレクトリの違い
- 14. 完全に純粋な仮想クラスのVtableの配置
- 15. C++での純粋仮想関数の使用方法は?
- 16. 純粋仮想クラス、1つの派生クラス、まだvtable?
- 17. 純粋な仮想メソッドを使用したC++クラスのクローニング
- 18. 純粋仮想関数の呼び出し方法
- 19. 仮想モニタ/仮想ディスプレイデバイスの作成
- 20. 仮想呼び出しは、純粋仮想メンバーのアドレスを使用します。それは合法ですか?
- 21. 純粋な仮想関数呼び出し
- 22. "純粋な仮想メソッド"を解決する方法
- 23. 純粋仮想継承、多重継承、およびC4505
- 24. 純粋仮想関数でC++クラスを使用するには?
- 25. JSonCppを使った純粋仮想関数呼び出し
- 26. 仮想関数オーバーライド仮想関数
- 27. ASP.NETと仮想ディレクトリ
- 28. 仮想メモリとsbrk
- 29. ポインタと仮想メモリ
- 30. 仮想メモリとリロケータブルコード
lol "grand-parent class" –
子のXYZも仮想です。キーワード 'virtual'が書かれていなくても、ベースのXYZは仮想ですので、パラメータリストが同じであれば子も同じです。 –