2017-10-21 26 views
3

virtual関数がどのように機能し、以下のコードが出力を出力しないのかを簡単に理解しようとしています。私が知る限り、moveMouth()virtualなので、talkクラスのmoveMouth()のバージョンを使用する必要があります。C++仮想関数の単純な例

/* 
* main.cpp 
* 
* Created on: Mar 29, 2015 
*  Author: Admin 
*/ 

#include <iostream> 

using namespace std; 

class talk{ 

public: 

    int a=5; 
    void moveMouth(){ 
     cout <<"blah blah blah"<<endl; 
    } 
}; 

class person : public talk { 

public: 
    int id; 
    person(int a): id(a) { 

    } 

    virtual void moveMouth(){ 
     //cout <<"word word word"<<endl; 
    } 


}; 

int main(){ 
    person* p = new person(0); 
    p->moveMouth(); 
    return 0; 
} 
+4

仮想関数として基本クラス関数を宣言する必要があります –

答えて

1

のように証明することができる出力はありません。余談として


親から親の関数を呼び出さないようにします。

あなたはその行動を望んでいた場合は、ただのすべての子に関数を宣言していない:継承された関数が呼び出されますので

class person : public talk { 

public: 
    int id; 
    person(int a) : id(a) { 

    } 

    //virtual void moveMouth(){ 
    // //cout <<"word word word"<<endl; 
    //} 


}; 

これは出力を印刷します。

#include <iostream> 
#include <vector> 

using namespace std; 

class talk{ 

public: 

    int a = 5; 
    virtual void moveMouth(){ // base function is virtual 
     cout << "blah blah blah" << endl; 
    } 
}; 

class person : public talk { 

public: 
    int id; 
    person(int a) : id(a) { 

    } 
    void moveMouth() override { // override is optional but confirms we're overriding 
     cout <<"I'm a person"<<endl; 
    } 
}; 

class dog : public talk { 

public: 
    int id; 
    dog(int a) : id(a) { 

    } 
    void moveMouth() override { // override is optional but confirms we're overriding 
     cout <<"I'm a dog"<<endl; 
    } 
}; 

int main(){ 
    talk* p = new person(0); 
    talk* d = new dog(0); 
    p->moveMouth(); 
    d->moveMouth(); 

    std::vector<talk*> talkers; // can store pointers to all the different talkers in a single structure 
    talkers.push_back(p); 
    talkers.push_back(d); 
    for(auto i : talkers) 
     i->moveMouth(); 
    return 0; 
} 
2

仮想関数に基本クラスを伝える必要があります。

すなわちさておき、int a..はprivateである必要がありますように、これ

class talk{ 

public: 

    int a=5; 
    virtual void moveMouth(){ 
     cout <<"blah blah blah"<<endl; 
    } 
}; 

にコードを変更する - 私の知る限りでは、カプセル化

4

を検索、moveMouth()virtualであるから、それは使用する必要がありますバージョンをtalkクラスに追加しました。

いいえ、それは多態性の仕組みではありません。基本クラスで使用すると、派生クラスに異なる動作を導入することができます。

この例では、personクラスの空の実装moveMouth()を呼び出します。

だけ派生クラスで宣言を省略し、基本クラスバージョンを呼び出すには:

class person : public talk { 
public: 
    int id; 
    person(int a): id(a) { 

    } 

    // Completely omit this if you want to call the base class function by default: 
    // virtual void moveMouth(){ 
     //cout <<"word word word"<<endl; 
    // } 
}; 

動作を変更できるようにするには、あなたは、基本クラスでvirtualとしての機能を宣言する必要があります。

class talk{ 

public: 

    int a=5; 
    virtual void moveMouth(){ 
    // ^^^^^^^ 
     cout <<"blah blah blah"<<endl; 
    } 
}; 

継承階層の多態性は、最初にvirtual関数を導入した時点から始まります。仮想関数メカニズムはへのポインタまたは参照を介した子クラスの関数を呼び出すことを可能にするので
ポリモーフィック行動が良く、この

int main(){ 
    talk* t = new person(0); 
    t->moveMouth(); 
    return 0; 
} 
1

あなたはそれがvirtualになりたい最初のクラスにvirtualとしてメソッドを宣言しなければならないためだ。ここでは


が提供されたコードに基づいて、仮想関数機構の一例です。

さらに、virtualの呼び出しは、クラス階層内の先祖へのポインタまたは参照がある場合に意味があります。すでにperson*がある場合は、すでにperson::talkであり、他の検索はありません。に、基本クラスのポインタを使用

void moveMouth() override { 
    cout <<"word word word" << endl; 
} 

、代わりのperson* p = new person(0);:派生クラスで

virtual void moveMouth(){ 
    cout <<"blah blah blah"<<endl; 
} 

オーバーライドそれを(人):

2

あなたは、基本クラス(通話)機能virtualをマークする必要があります派生クラス:

多型性を利用するにはhavior。

関連する問題