简体   繁体   English

从虚函数调用派生类的成员

[英]Calling member of Derived class from virtual function

I'm a little bit confused concerning virtual functions. 我对虚函数有些困惑。

Lets suppose you have Base class with virtual function foo(), and that function then overridden in Derived class 假设您有带有虚拟函数foo()的基类,然后在派生类中覆盖了该函数

   class Baseclass
   {  
   public:
       virtual void foo()
       {
           //...
       }
   };

   class Derived: public BaseClass
   {
   private:
       int member_val;
   public:
       Derived( int init )
           : member_val( init )
       {}
       void foo()
       {
           member_val++;
       }
   };

and foo using member value of Derived class, when i write this code 当我编写这段代码时,和foo使用派生类的成员值

Derived d( 10 );
Base* bPtr = &d;
bPtr->foo(); 

foo() called for Derived class because _vptr points on "Derived class virtual table", and pointer in "Derived class virtual table" points on foo() from Derived class, but how then it found member_val, cause Base pointer doesn't know about it. foo()调用了Derived类,因为_vptr指向“ Derived class virtual table”,而“ Derived class virtual table”中的指针指向Derived class的foo(),但是后来如何找到member_val,导致Base指针不知道关于它。 What "this" is passed to foo() from Derived class. 什么“ this”从派生类传递给foo()。 We call it for Base* (this is Base type) but to find member_val we need Derived* ( this Derived type). 我们称它为Base *(这是Base类型),但是要找到member_val,我们需要Derived *(此Derived类型)。 So how it works under the hood? 那么它是如何工作的呢?

Right question is half an answer. 正确的问题是成功的一半。 Like in your case, you asked what this is passed to Derived::foo() , and the answer is "the same". 像你的情况,你问this传递给Derived::foo()得到的答复是“相同的”。 You create an object of class Derived . 您创建一个类Derived的对象。 It is allocatied in memory like the following: 它在内存中的分配方式如下:

Derived:
--------
vptr_t* vptr
int member_val

You then cast the &d , which is Derived* to Base* . 然后,将&dDerived*Base* What happened to the pointer? 指针出了什么事? Nothing. 没有。 It just changed its type, not the actual address it is pointing to. 它只是更改了其类型,而不是所指向的实际地址。 You can than convert it back to Derived* using dynamic_cast<Derived*>() or even static_cast<Derived*> . 你可以比其转换回Derived*使用dynamic_cast<Derived*>()甚至static_cast<Derived*> It is absolutely safe to use both in this case. 在这种情况下,同时使用这两种方法绝对是安全的。

So the only actual question is how the table of virtual functions works? 因此,唯一的实际问题是虚函数表如何工作? But this is another question, and it seems like you understand it. 但这是另一个问题,似乎您理解它。

Please note: things are more complicated with multiple inheritance, when several base classes are located in memory one after another. 请注意:当多个基类一个接一个地位于内存中时,多重继承会使事情变得更加复杂。

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

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