虚関数の重要な性質の総括


実行時のクラス関数の多状態挙動を常に虚関数で完了する.これは基本的です.
 
しかし、私たちはこのような問題を考えていますか?
クラス階層で関数多様性を実装したい場合は、クラス階層のベースクラスに虚関数を追加し、派生クラスを順次書き換えることを考えます.
しかし、虚関数を直接呼び出すだけでマルチステート動作が実現できるのではないでしょうか.
 
私たちの関数の間で相互に呼び出すことができることを忘れないでください.あなたも私が直接言っているのを見ています.したがって、ベースクラスの一般関数を使用して、この一般関数に虚関数を呼び出し、派生クラスがベースクラスの一般関数を直接呼び出すことでマルチステートを実現することができます.これらのものは簡単に言えます.しかし、実際に活用し、適切に使うには、高いレベルが必要ですね.実は以上提案したこの2つの方法の本質はいずれも虚関数を利用した多態挙動である.しかし、後者も実際に使われることが多く、初心者も誤解し、その中の玄機が分からないことが多い.
 
クラスカットの注意点:
class A
{
public:
 A(){cout<<"A's default construction is invoked!"<<endl;}
 ~A(){cout<<"A's destruction is invoked!"<<endl;}
 A( const A& rhs ){cout<<"A's copy construction is invoked!"<<endl;}
 virtual void Show() const{cout<<"A's Show"<<endl;}
};

class B:public A
{
public:
 B(){cout<<"B's construction is invoked!"<<endl;}
 ~B(){cout<<"B's destruction is invoked!"<<endl;}
 virtual void Show() const {cout<<"B's Show"<<endl;}
};

main()
{
    B b;
    ((A)b).Show();
}

その出力は何ですか?
 
答えは次のとおりです.
A's default construction is invoked! B's construction is invoked! A's copy construction is invoked! A's Show A's destruction is invoked! B's destruction is invoked! A's destruction is invoked!
 
なぜなら、(A)b)はC++の重要なオブジェクトカットであり、このカットはbオブジェクトに一時的なAクラスオブジェクトを生成するからである.新しいオブジェクトなので、呼び出された虚関数はAクラスです.
 
main()の場合
{
    B b;
    ((A&)b).Show();
}
その出力は何ですか?
 
答えは次のとおりです.
A's default construction is invoked! B's construction is invoked! B's Show B's destruction is invoked! A's destruction is invoked!
なぜなら、((A&)b)は、bをA&に渡す匿名のオブジェクトに相当し、参照のために新しいオブジェクトが作成されていないのか、元のオブジェクトの別の別名なのか、ポインタの多態性を有しているからである.
 
また,クラス関数でクラス役割ドメインシンボルで虚関数を呼び出す方式では多態性ではなく,単純に対応クラスの対応関数を呼び出すことが混同されやすい.覚えておいて!