在 C++ 中,如何测试对象是不是是父类构造函数中子类的实例?
Posted
技术标签:
【中文标题】在 C++ 中,如何测试对象是不是是父类构造函数中子类的实例?【英文标题】:In C++, how can I test if an object is an instance of a Child class in the Parent class' constructor?在 C++ 中,如何测试对象是否是父类构造函数中子类的实例? 【发布时间】:2011-09-16 00:09:51 【问题描述】:我试图断言传递给父类的构造函数的指针只有NULL
,如果对象是特定使用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
然而,我希望在Child2
构造期间看到ERROR
仅。
为什么当我在从Child1
的构造函数初始化列表调用Child1
的Parent
构造函数时,dynamic_cast
返回非NULL?另外,有没有其他方法可以完成这个测试?
【问题讨论】:
感觉这样的设计会违反继承的“is-a”关系…… 1) 为什么要这样做? 2)你不能这样做的原因是孩子还没有被构造出来。 因为实际上,我有 10 个不同的子类必须具有非 NULL 指针,但只有 1 个子类将具有 NULL 指针。我试图避免将此检查放在 10 个不同的类中。 @Ross:你为什么不在Parent
中使用静态辅助函数呢? private: static void checkPointer(void *ptr, bool b) if (ptr == NULL && !b) std::cerr << "ERROR\n";
.
这仍然违反 D.R.Y. (而且我知道我违反了 KISS :-)),但你给了我一个不同的想法。我可以实现我在访问器方法中编写的 exact 相同的检查,dynamic_cast
将起作用。我想做这个废话的原因是我可以控制Parent
和Child1
,但我无法控制所有其他Child2
... ChildN
。
【参考方案1】:
当您在 Parent 构造函数中 - 它是一个基类 - Child 尚未构造。因此,在 Parent 的构造函数中 this 的动态类型将始终是 Parent。
【讨论】:
那么RTTI信息是由每一级构造函数迭代构建的? 不,RTTI 信息是静态的并且在编译时构建。在构造函数和析构函数中,派生类尚未构建或已被销毁。但是你可能会说,对象的动态类型是由每一级构造函数迭代构建的。【参考方案2】:我猜问题是 dynamic_cast 在 vtable 上工作,直到构造函数完成后才设置。因此,您不能在构造函数中调用 dynamic_cast。
我想不出任何直接的方法来在构造函数中检测到这一点,而无需使用模板并使所有内容都变为静态。你为什么想要这种行为?看起来很可疑 - Parent 真的不应该知道 Child1 和 Child2 的派生词。
如果你想在 Child2 调用父构造函数时防止空指针,为什么不在 Child2 的构造函数中防止它,如果它为空则抛出异常?
【讨论】:
有很多 Child2 的。我试图避免将支票放在一大堆课程中。 为什么不创建一个 CheckedParent 类,并从中派生 Child2s?【参考方案3】:这样做的一种方法是在基类中创建 proected 构造函数,并传递指示如何初始化它的参数 - 这样子类将决定他们想要它的方式,而基类将根据要求安排事情。
【讨论】:
以上是关于在 C++ 中,如何测试对象是不是是父类构造函数中子类的实例?的主要内容,如果未能解决你的问题,请参考以下文章