2012-02-19 12 views
0

仮想関数の目的を理解したい。本当に仮想関数は何ですか?

メンバ関数が非仮想でこのコード分析できます:

例1:我々はa->foo1()の出力を見るよう

struct A 
{  
    void foo1() { cout << "foo 1 from A \n"; } 
}; 

struct B : A 
{ 
    void foo1() { cout << "foo 1 from B \n"; } 
}; 

int main() 
{ 
    A *a = new B; 
    a->foo1(); // will print "foo 1 from A \n" because A::foo1 isn't virtual 

    B *b = new B; 
    b->foo1(); // will print "foo 1 from B \n" 
} 

と、 "Aからのfoo 1"になりますが、私はB自身のfoo1関数を実行するように機能します。だから私はそれをオーバーライドしてA::foo1仮想関数を作る必要があります。

例2:我々はそれがしたいと今

struct A 
{ 
    virtual void foo1() { cout << "foo 1 from A \n"; } 
}; 

struct B : A 
{ 
    void foo1() { cout << "foo 1 from B \n"; } 
}; 

int main() 
{ 
    A *a = new B; 
    a->foo1(); // will print "foo 1 from B \n" 

    B *b = new B; 
    b->foo1(); // will print "foo 1 from B \n" 
} 

A::foo1はオーバーライドとa->foo1()印刷物 "BからFOO 1" されました。しかし、のは、クラスBが中に存在していないいくつかの機能を持っている場合を考えてみましょう:

例3:

struct A 
{ 
    int a; 
    void foo1() { cout << "foo 1 from A \n"; } 
}; 

struct B : A 
{ 
    int b; 
    void foo1() { cout << "foo 1 from B \n"; } 
    void foo2() { cout << "foo 2 from B \n"; } 
}; 

int main() 
{ 
    A *a = new B; 
    // a->foo2(); // compiler error, a doesn't see foo2 function 
    a->foo1(); 
    // a->b = 1; // compiler error, a doesn't see member variable b 
    a->a = 1; 

    // We aren't going to do B *b = new A; here because that's nonsense 
    B *b = new B; 
    b->foo2(); // ok 
    b->foo1(); // ok 
    b->b = 1; // ok 
    b->a = 1; // ok 
} 

我々はBがの正確なコピーではありません、今見たよう。 Aを継承し、いくつかの新しい関数と変数で拡張します。 a->foo2()またはa->bはできません。

A *a = new B;のような文章は、コードを読んだり解析するときには、B *b = new B;よりもずっと混乱していると思います。

私はbがBのインスタンスへのポインタであることを知っています。A*が指し示すオブジェクトのタイプが何であるか疑問に思うのは混乱しませんか?

私の質問は次のとおりです。仮想関数を使用するにはどうすればよいですか?

基本クラスに変数や関数がない場合、派生クラスでは使用しません。 B *b = new B;ではなく、A *a = new B;を使用して新しいオブジェクトを作成する方がはっきりしています。

B *b = new B;を使用してBのインスタンスを作成すると、Bは自動的にA::foo1を自身のfoo1で上書きするため、Aのメンバー関数は仮想である必要はありません。

したがって、仮想関数の唯一の用途は、実行時に機能を変更したいときです。おそらく、

我々は、実行時に実行されたクラスを変更したいときには、このような場合に有用である可能性:

:関数に引数を渡すときに代わり

A *a; 
B b; 
C c; 

a = &B; 
a->foo1(); 
a = &C; 
a->foo1(); 

、これは有用である可能性があります

void execute(A *a) 
{ 
    a->foo1(); 
} 

私はこれについて何か不足していますか?

+3

投稿を正しくフォーマットしてください。 SOをしばらく見て、それがどのように行われたかを見て、編集ヘルプを読んでください。 –

+3

あなたにはC++の本がないことは明らかです。どうぞ[今すぐ直す](http://jcatki.no-ip.org/fncpp/Resources)。 –

+0

そして、はい、4ヶ月は、SOの投稿を書く方法を理解するのに十分です。あなたは以前に尋ねられました。 –

答えて

3

仮想関数は、実行時の多態性を実装する主な方法です。多形性をGoogleで検索すると、その技術について有用なものが表示される場合があります。

0

仮想関数は、C++が多態性の概念を実装する方法です。

C++では、コンパイル時にコンパイラがメソッドをバインドするコンパイル時の多態性に、単純なメソッドオーバーロードが使用されます。

仮想関数の場合、コンパイラは必要に応じてランタイム中にメソッドを使用します。

関連する問題