c++ - 在 C++ 中作为参数传递的对象中执行方法

标签 c++ virtual

我有一个 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/

相关文章:

c++ - 在 Debian 上使用 AX_BOOST_BASE 找不到 boost

c++ - 无法重载虚函数

c++ - 为什么我的虚拟函数 "unique"不工作?

c++ - 广度优先搜索修剪和内存泄漏 C++

c++ - 函数模板与重载混合

c++ - 我如何逐行读取灰度图像 opencv c++

c++ - clang 与 gcc : variadic lambda captures

C++ 工厂制造和多态性 -> 调用映射迭代器访问的实例的子类虚方法

C++ lnk error 2019 unresolved external symbol virtual errors because of an interface...(?)

来自 Rosenberg 的虚拟装置