简体   繁体   English

类成员函数内的虚拟函数调用

[英]virtual function call within a class member function

I understand the basic concept of virtual function and vtable, but in the following example, I don't understand why cA(); 我了解虚函数和vtable的基本概念,但是在以下示例中,我不明白为什么使用cA(); prints out 打印出来

parent A
child

but without the virtual keyword for Parent::func(), it prints out 但没有Parent :: func()的虚拟关键字,它将输出

parent A
parent

Would you let me know the reason in detail? 您能详细告诉我原因吗? It would be great to explain with v table, memory (heap, stack), etc.. 用v表,内存(堆,堆栈)等进行解释将非常有用。

Thanks. 谢谢。

#include <iostream> 

template <class TYPE> class Parent
{
public:
    Parent() {};
    ~Parent() {};
    virtual void func() { std::cout << "parent" << std::endl; };

    void A() {
        std::cout << "parent A" << std::endl;
        func();
    }

};

template <class TYPE> class Child : public Parent <TYPE>
{
public:
    Child() {};
    ~Child() {};

    void func() { std::cout << "child" << std::endl; };
};

void main()
{
    Child<int> c;
    c.A();
}

The virtual key word specifies that the function can be redefined in a derived class, while preserving its calling properties though references. 虚拟关键字指定可以在派生类中重新定义函数,同时通过引用保留其调用属性。 This is basically the trigger for polymorphic behavior. 这基本上是多态行为的触发器。 If the function is declared virtual and it is redefined in a derived class then the vtable is utilized to select the appropriate version of the function unless a specific namespace is specified. 如果将函数声明为虚拟函数,并且在派生类中对其进行了重新定义,则除非指定了特定的名称空间,否则将使用vtable选择函数的适当版本。 For example Parent::func(). 例如Parent :: func()。 Despite having the same name, without the key word virtual the two functions you named func() are completely different. 尽管名称相同,但没有关键字virtual,您命名为func()的两个函数完全不同。 There is no reference available to the base class that can access the derived class's version of the function. 对于可访问派生类的功能版本的基类,没有可用的引用。 It uses the only version func() it knows about, which is the one defined in the base class. 它使用它知道的唯一版本func(),这是基类中定义的版本。

@Pemdas gave a nice explanation. @Pemdas提供了一个很好的解释。 Here is my try. 这是我的尝试。

cA() tells compiler "I am gonna call the non virtual function A defined in my parent class". cA()告诉编译器“我将调用父类中定义的非虚函数A”。 This translates to Parent::A(&c) 转换为Parent::A(&c)

The A method in class Parent translates to "get the vtable of object &c, grab the function pointer in first row, and call it". Parent类中的A方法转换为“获取对象&c的vtable,获取第一行中的函数指针,然后调用它”。 Since c reimplements the function func , the function pointer would be c 's implementation of function func . 由于c重新实现了函数func ,所以函数指针将是c对函数func的实现。 That would be what you see. 那就是你所看到的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM