Reputation: 24228
I'm trying to assert that a pointer passed into a Parent class' constructor is only NULL
if the object is of a specific Child class type using dynamic_cast
:
#include <iostream>
class Parent {
public:
Parent(void *ptr);
virtual ~Parent(); // to make Parent polymorphic
};
class Child1 : public Parent {
public:
Child1() : Parent(0) { std::cout << "Child1 ctor\n";};
};
class Child2 : public Parent {
public:
Child2() : Parent(0) { std::cout << "Child2 ctor\n";};
};
Parent::Parent(void *ptr) {
if (0 == ptr && 0 == dynamic_cast<Child1*>(this)) {
std::cerr<<"ERROR\n";
}
}
Parent::~Parent() {};
int main(void) {
Child1 *c1 = new Child1();
Child2 *c2 = new Child2();
}
This prints:
ERROR
Child1 ctor
ERROR
Child2 ctor
Whereas, I expect to see ERROR
during the Child2
construction only.
Why is dynamic_cast
returning non-NULL when I'm in Parent
constructor for Child1
called from Child1
's constructor initialization list? Also, is there a different way to accomplish this test?
Upvotes: 1
Views: 1472
Reputation: 6181
One way to do thins like that would be to create proected constructor in base class, and pass parameter indicating how to initalize it - this way child classes would decide how they want it, and base class would just arrange things as requested.
Upvotes: 0
Reputation: 26
I'd guess the issue is that dynamic_cast works off the vtable, which isn't set up until after the constructor finishes. Thus, you can't call dynamic_cast in the constructor.
I can't think of any immediate ways to detect this in the constructor without using templates and making everything static. Why do you want this behaviour? It seems quite dubious - Parent really should have no knowledge of the derivatives Child1 and Child2.
If you want to protect against a null pointer in when Child2 calls the parent constructor, why not just protect against it in Child2's constructor and throw an exception if it is null?
Upvotes: 1
Reputation: 81349
When you are in Parent constructor -which is a base class- the Child has not been constructed yet. As a result, within the constructor of Parent the dynamic type of this will always be Parent.
Upvotes: 2