如果对象是使用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_cast
在Parent
构造函数Child1
从Child1
的构造函数初始化列表调用时返回非NULL?另外,有没有不同的方法来完成这个测试?
答案 0 :(得分:2)
当你在Parent构造函数中 - 它是一个基类时 - 尚未构造Child。因此,在Parent的构造函数中,它的动态类型将始终为Parent。
答案 1 :(得分:1)
我猜测问题是dynamic_cast在vtable上运行,直到构造函数完成后才会设置。因此,您无法在构造函数中调用dynamic_cast。
在没有使用模板并使一切都静止的情况下,我无法想到在构造函数中检测到这种情况的任何直接方法。你为什么想要这种行为?这看起来很可疑 - 家长真的不应该知道衍生物Child1和Child2。
如果你想在Child2调用父构造函数时防止空指针,为什么不在Child2的构造函数中防止它,如果它为null则抛出异常?
答案 2 :(得分:0)
这样做的一种方法是在基类中创建proected构造函数,并传递指示如何初始化它的参数 - 这样子类会决定他们想要的方式,而基类只会根据请求排列。