在C ++中,如何在Parent类的构造函数中测试对象是否是Child类的实例?

时间:2011-09-16 00:09:52

标签: c++

如果对象是使用NULL特定子类类型,我试图断言传递给Parent类构造函数的指针只有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();
}

打印:

ERROR
Child1 ctor
ERROR
Child2 ctor

然而,我希望在ERROR构建期间只看到Child2

为什么dynamic_castParent构造函数Child1Child1的构造函数初始化列表调用时返回非NULL?另外,有没有不同的方法来完成这个测试?

3 个答案:

答案 0 :(得分:2)

当你在Parent构造函数中 - 它是一个基类时 - 尚未构造Child。因此,在Parent的构造函数中,它的动态类型将始终为Parent。

答案 1 :(得分:1)

我猜测问题是dynamic_cast在vtable上运行,直到构造函数完成后才会设置。因此,您无法在构造函数中调用dynamic_cast。

在没有使用模板并使一切都静止的情况下,我无法想到在构造函数中检测到这种情况的任何直接方法。你为什么想要这种行为?这看起来很可疑 - 家长真的不应该知道衍生物Child1和Child2。

如果你想在Child2调用父构造函数时防止空指针,为什么不在Child2的构造函数中防止它,如果它为null则抛出异常?

答案 2 :(得分:0)

这样做的一种方法是在基类中创建proected构造函数,并传递指示如何初始化它的参数 - 这样子类会决定他们想要的方式,而基类只会根据请求排列。