在大多数派生类类型上未调用虚函数

Virtual function not called on most derived class type

本文关键字:调用 函数 类型 大多数 派生      更新时间:2023-10-16

Edit 已解决并重新发布为示例程序

场景如下:

类层次结构:

class Base
{
public:
   virtual void output() = 0;
private:
   int a;
};
class Derived_1 : public Base
{
public:
   virtual void output()
   {
      cout << "Derived_1" << endl;
   }
};
class Derived_2 : public Derived_1
{
public:
   virtual void output()
   {
      cout << "Derived_2" << endl;
   }
};

实现:

Derived_2* obj = reinterpret_cast<Derived_2*>(new Derived_1());
obj->output();

这将输出"Derived_1"而不是"Derived_2"。我相信这对你们大多数人来说并不是什么新鲜事,但这是我在应用程序中制作一些工厂功能时没有想到的事情。

您正在分配一个Value_object_data对象,而不是Value_object_uint32 。您将其转换为Value_object_uint32这一事实不会改变任何事情。实际对象的虚拟表不知道Value_object_uint32;在其虚拟函数表中,该表是在错误时构建的...建设,format指向Value_object_dataformat。强力武装指向实际对象的指针类型对解决这种情况没有任何作用。

给定层次结构中所有基类和继承类的构造函数从派生最多的类到根类调用一次,每个类恰好调用一次。这意味着,您不必显式调用基类构造函数。它将自动调用。如果需要指定应使用多个基类构造函数中的哪一个,也可以这样做:

class Base
{
public:
    Base() {} // default constructor
    Base(int a) {}
};
class Derived
{
public:
    Derived() : Base()
    {
    }
    Derived(int a)
      : Base(a) // Select the Base ctor that takes an int, instead of the default
    {
    }
};
int main()
{
    Derived d1;    // Calls Derived() and Base() ctors in this order
    Derived d2(5); // Calls Derived(5) and Base(5) in this order
}

当然,Derived(int a)构造函数不需要调用Base(int)构造函数。在这种情况下,将自动调用Base()构造函数。

编辑 此答案基于发布的原始代码。 OP 在看到截断的示例按预期工作后更新了代码示例。


您的代码并不完全正确,但发生此类事件的最常见原因是,当您尝试覆盖时,您没有完全正确地获得签名,而是创建了重载。 当您通过基类调用时,它仍将调用正确定义的基类。

签名中的一切都很重要 - 一个常见的错误是方法的恒定性是签名的一部分。

至少,new_VO_data()方法被破坏了。由于可变的虚拟表大小和可变填充,它可能会也可能不会起作用,这些大小和填充是标准的任意的,并且取决于编译器选项。简单地说,行为是不确定的。