0

所以我有一个 C++ 函数,我将一个指向基类的指针传递给它,例如:

void DoStuffAndAssignPtr(MyBase* ptr)
{
    MyBase* p;
    //do stuff
    if (stuff was awesome) p = new MyAwesome();
    else p = new MyBase();
          //vftable of p before the return is MyAwesome
    (*ptr) = (*p);
}

现在我们需要调用一些“MyAwesome”和“MyBase”实现不同的虚拟方法。但是,在检查返回值时,如下所示:

void mainly()
{
    MyBase* passMe = new MyBase();
    DoStuffAndAssignPtr(passMe);
    //now passMe is always being returned with MyBase's vftable
}

我们可以看到“passMe”始终是“MyBase”(就在 VS 中调试时的 vftable 显示而言)。谁能提供任何关于为什么会发生这种情况的指导,以及我如何确保“passMe”将调用虚拟方法的“MyAwesome”实现?

4

2 回答 2

3

问题在于使用(*ptr)=(*p). 你应该使用ptr=p.

只有指针和引用具有多态性。当您使用取消引用(星号 *)时,您将丢失此属性,并且仅将基础部分从 复制pptr。这是因为ptr只有那部分信息的空间。

于 2013-01-29T21:08:02.240 回答
3

您有对象切片问题,下面的语句将 MyAwesome 对象切片到 MyBase:

(*ptr) = (*p)

您只传递MyBase*给 DoStuffAndAssignPtr 并尝试分配一个只会覆盖函数参数副本的新指针。您需要改为传递指针的引用。

void DoStuffAndAssignPtr(MyBase*& ptr);
                                ^^^

此外,由于 passMe 已经由新的外部 DoStuffAndAssignPtr 分配,因此您在 DoStuffAndAssignPtr 内为 ptr 创建了另一个内存,这将导致内存泄漏。

更好的解决方案是:

MyBase* MakeAClass()
{
   if (stuff was awesome)
   {
       return new MyAwesome();
   }
   return new MyBase();
} 

int main()
{
  MyBase* passMe = MakeBase()
}
于 2013-01-29T21:11:36.030 回答