知道基类指针指向哪个派生类
Posted
技术标签:
【中文标题】知道基类指针指向哪个派生类【英文标题】:Knowing which derived class a base class pointer points to 【发布时间】:2015-11-24 06:02:44 【问题描述】:假设我有一个 Animal 类和两个类 - Dog 和 Cat 派生自它。 这样做是完全合法的 -
Dog d;
Cat c;
Animal* a1 = &c;
Animal* a2 = &d;
现在,给定 a1 和 a2,我能知道这个指针指向哪个派生类吗?
我现在唯一的想法是在 Animal 类中再添加一个成员字段并在构造函数中对其进行初始化。这甚至是一个好习惯吗?
【问题讨论】:
不,这不是一个好习惯。这通常表明还有更多的事情要做。 【参考方案1】:是的,它是合法的,是的,这是回到原始类型的一种方式。您也可以使用 dynamic_cast,但这有开销。一般程序将其存储在派生类型中,仅在无关紧要时与基类一起引用它。
我发现如果你必须做类似 dynamic_cast 的事情,你必须重新考虑你的程序设计。
【讨论】:
【参考方案2】:您可以使用 dynamic_cast 找出答案。 Dynamic_cast 使用运行时类型检查,如果无法进行相应转换,则会失败。
ex: Derived* d = dynamic_cast<Derived*>(base)
另外,如果你使用 VStudio,你可以使用
typeid(*a1).name.
这会给你 a1 指针指向的类名。
【讨论】:
typeid 不仅仅是 Visual Studio 的东西。 不是假设我知道基指针的类型吗?在我的问题中,我会写Cat* ptr = dynamic_cast<Cat*>a1
还是Dog* ptr = dynamic_cast<Dog*>a1
?
是的。但是由于 dynamic_cast 是安全强制转换(检查运行时类型信息以确保可以进行有意义的转换),您将获得指向请求类型的有效指针或 null。如果你不知道指向的对象,那么使用 typeid(*a1).name="Cat" , typeid(*a1) == "dog"【参考方案3】:
我同意多米尼克的观点。我只想在这里补充两点,dynamic_cast
开销因编译器而异,如果您没有重新设计程序的选项,那么您别无选择,只能使用dynamic_cast
。(以防万一(不是您的问题)如果您确定类型然后总是更喜欢使用static_cast
,它的开销非常少。)
【讨论】:
这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review @Bartłomiej Semańczyk...答案是按照其他人的建议使用 dynamic_cast。【参考方案4】:我建议添加一个字段。
正如其他人所提到的,dynamic_cast<T>()
可以使用,但您需要小心并知道它何时有效,何时无效。要让它工作,您需要 RTTI(运行时类型信息),它并不总是存在/有效(例如在使用库时等)
我同意@Dominic McDonnell:
我发现如果你必须做类似 dynamic_cast 的事情,你必须重新考虑你的程序设计。
PS:如果您使用的是 Qt,那么您可以使用 qobject_cast<T>()
,因为 Qt 将此类信息添加到 QObject
类型的对象中而不需要 RTTI
【讨论】:
以上是关于知道基类指针指向哪个派生类的主要内容,如果未能解决你的问题,请参考以下文章