我有一个 Rabbit 结构,以及继承它的 CrazyRabbit 结构。 当我执行这段代码时:
#include <iostream>
using namespace std;
struct Rabbit {
virtual void sayCry() {
cout << "..." << endl;
}
};
struct CrazyRabbit : Rabbit {
void sayCry() { cout <<"Moo"<< endl; }
};
void foo(Rabbit r, Rabbit* pr, Rabbit& rr) {
r.sayCry();
pr->sayCry();
rr.sayCry();
}
int main(int argc, char *argv[]) {
Rabbit *pr = new CrazyRabbit();
foo(*pr, pr, *pr);
}
我得到了结果:
...
Moo
Moo
为什么第一种情况执行父类(super class)中的方法? C++中是否定义了执行规则?
最佳答案
foo() 的第一个参数类型不是指针,您实际上所做的是复制到父类(super class)的实例中。这是因为当您实际调用该函数时,每个函数参数都会使用您提供的任何参数进行初始化。因此,就好像您已完成以下操作:
Rabbit r = *pr; // (from your main()) object slicing happens here
Rabbit* pr = pr; // (the rhs pr is from your main(), not the pr from foo())
Rabbit& rr = *pr; // (from your main())
因此,在第一种情况下,您只需声明 Rabbit 类型的对象并分配其派生类,这会导致对象切片,这意味着属于派生类 CrazyRabbit 的任何数据都会丢失,剩下的唯一数据是属兔类型。
对于虚函数调用,您需要一个指针。在运行时,C++将检查vptr和vtbl以正确识别要调用哪个虚拟函数。
关于c++ - 在 C++ 中作为参数传递的对象中执行方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31870063/