编辑已解决并重新发布为示例程序
情景如下:
类层次结构:
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”。我相信这对你们大多数人来说并不是什么新鲜事,但是在我的应用程序中制作我的一些工厂函数时,我没有想到这一点。
答案 0 :(得分:3)
编辑此答案基于发布的原始代码。在看到截断的示例按预期工作后,OP更新了代码示例。
您的代码不完全正确,但发生此类事件的最常见原因是,当您尝试覆盖并且创建了重载时,您没有完全正确地获取签名。当您通过基类调用时,它仍将调用正确定义的基类。
签名中的所有内容都很重要 - 一个常见的错误是方法的常量是签名的一部分。
答案 1 :(得分:3)
您正在分配Value_object_data
个对象,而不是Value_object_uint32
。您将其作为Value_object_uint32
进行投射的事实一无所获。实际对象的虚拟表不知道Value_object_uint32
;在虚构函数表中,它是在构造错误时构造的,format
指向Value_object_data
的{{1}}。强指向指向实际对象的指针类型无法解决问题。
给定层次结构中所有基类和继承类的构造函数从最派生到根调用,每个类只调用一次。这意味着,您不必显式调用基类构造函数。它会自动调用。如果需要指定应该使用几个基类构造函数中的哪一个,那么也可以这样做:
format
当然,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)
构造函数将自动调用。
答案 2 :(得分:0)
至少,new_VO_data()
方法已被破坏。由于可变的虚拟表大小和可变填充,它可能或可能不起作用,它们是标准的任意值并且取决于编译器选项。简单地说,行为是未定义的。