Ross Rogers
Ross Rogers

Reputation: 24228

In C++, how can I test if an object is an instance of a Child class in the Parent class' constructor?

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

Answers (3)

j_kubik
j_kubik

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

Andrew
Andrew

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

K-ballo
K-ballo

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

Related Questions