尝试快速了解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;
}
答案 0 :(得分:4)
据我所知,由于
virtual
为moveMouth()
,因此应使用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*
而没有其他查找。