Reputation: 4457
Edit Solved and Reposted as sample program
The scenario was as follows:
The class hierarchy:
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;
}
};
The implementation:
Derived_2* obj = reinterpret_cast<Derived_2*>(new Derived_1());
obj->output();
This will output "Derived_1" and not "Derived_2". I'm sure this is nothing new to most of you, but it was something I didn't think about when making some of my factory functions in my application.
Upvotes: 1
Views: 1246
Reputation: 89192
EDIT This answer is based on the original code posted. The OP updated the code sample after seeing that the truncated example worked as expected.
Your code isn't exactly right, but the most common reason for something like this to happen is that you didn't get the signature exactly right when you tried to override and you created an overload instead. When you call through the base class, it will still call the one defined correctly.
Everything in the signature matters -- a common mistake is that the constness of the method is part of the signature.
Upvotes: 3
Reputation: 1024
You are allocating a Value_object_data
object, not Value_object_uint32
. The fact that you're casting it as a Value_object_uint32
changes nothing. The actual object's virtual table has no knowledge of Value_object_uint32
; in its virtual function table, which is constructed at the time of err... construction, format
points to Value_object_data
's format
. Strong-arming the type of pointer which points to the actual object does nothing to fix the situation.
Constructors for all base and inherited classes in a given hierarchy are called from the most derived to the root, exactly once for each class. This means, you don't have to explicitly call the base class constructor. It will be called automatically. If you need to specify which of several base class constructors should be used you can do that too:
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
}
Of course, the Derived(int a)
constructor is not required to call the Base(int)
constructor. In this case the Base()
constructor will be called automatically.
Upvotes: 3
Reputation: 5225
At least, the new_VO_data()
method is broken. It may or may not work due to variable virtual table size and variable padding, which are arbitrary by standard and depend on compiler options. Simply put, the behaviour is undefined.
Upvotes: 0