0

我对虚拟功能有点困惑。

假设您有带有虚函数 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++;
       }
   };

和 foo 使用派生类的成员值,当我编写此代码时

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

foo() 调用派生类,因为 _vptr 指向“派生类虚拟表”,而“派生类虚拟表”中​​的指针指向派生类的 foo(),但是它如何找到 member_val,导致基指针不知道关于它。什么“this”从 Derived 类传递给 foo()。我们称它为 Base*(这是 Base 类型),但要找到 member_val,我们需要 Derived*(此 Derived 类型)。那么它是如何在引擎盖下工作的呢?

4

1 回答 1

0

正确的问题是一半的答案。就像你的情况一样,你问this传递给了什么Derived::foo(),答案是“相同的”。您创建一个 class 对象Derived。它在内存中分配如下:

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

然后你施放&d,即Derived*to Base*。指针怎么了?没有什么。它只是改变了它的类型,而不是它指向的实际地址。您可以将其转换回Derived*usingdynamic_cast<Derived*>()甚至static_cast<Derived*>. 在这种情况下使用两者都是绝对安全的。

所以唯一的实际问题是虚函数表是如何工作的?但这是另一个问题,看起来你明白了。

请注意:当多个基类一个接一个地位于内存中时,多重继承会使事情变得更加复杂。

于 2013-06-20T21:25:35.703 回答