C ++虚函数简单的例子

时间:2017-10-21 14:09:03

标签: c++

尝试快速了解virtual函数的工作原理,不确定下面的代码为什么不打印任何输出。据我所知,由于moveMouth()virtual,因此应使用moveMouth()类中talk的版本。

/*
 * 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;
}

5 个答案:

答案 0 :(得分:4)

  

据我所知,由于virtualmoveMouth(),因此应使用talk类中moveMouth()的版本。

不,这不是多态的工作原理。它允许您在基类中使用时在派生类中引入不同的行为。

您的示例从person类调用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; } 函数开始。

暂且不说:
像这样可以更好地证明多态行为

tf.nn.dynamic_rnn

答案 1 :(得分:2)

您需要告诉基类虚函数。

即。将代码更改为此

int a..

顺便说一下,int i = 0; if (condition){ i = userinput; } 应该是私有的 - 查找封装

答案 2 :(得分:2)

您需要标记基类(talk)函数virtual

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

在派生类(Person)中覆盖它:

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

而不是person* p = new person(0);使用基类指针到派生类:

talk* p = new person(0);

利用多态行为。

答案 3 :(得分: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;
}

答案 4 :(得分:1)

这是因为您必须在第一个类if (propertyLamdba.Body.NodeType == ExpressionType.TypeAs) member = ((propertyLamdba.Body as UnaryExpression).Operand as MemberExpression).Member 中声明方法为virtual

此外,当您在类的层次结构中有一个指向祖先的指针或引用时,virtual invokation是有意义的。如果您已经有virtual,那么在您的情况下它已经person*而没有其他查找。