这样更容易解释一个例子,
class base {
//....
}
class derived1 : public base {
//...
}
在我的库中,有一个基类的指针。库的用户必须从基类或派生类派生类,并将指针分配给该类。
如何检查用户定义的类是从哪个类派生的?
原文由 khajvah 发布,翻译遵循 CC BY-SA 4.0 许可协议
这样更容易解释一个例子,
class base {
//....
}
class derived1 : public base {
//...
}
在我的库中,有一个基类的指针。库的用户必须从基类或派生类派生类,并将指针分配给该类。
如何检查用户定义的类是从哪个类派生的?
原文由 khajvah 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以通过多种方式做到这一点。正如其他人指出的那样,最常见的是 dynamic_cast<> 和 std::is_base_of 。后者在编译时使用,而 dynamic_cast<>
可以在运行时使用。但是,--- dynamic_cast<>
仅 在您的源类是多态的(即至少具有一个虚函数 - 它可以是方法或其析构函数)时才有效。如果不是,编译器将触发错误。
原文由 Iosif Murariu 发布,翻译遵循 CC BY-SA 3.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
我对提议的编译时 x 运行时解决方案有一些评论。除了评估时间之外,
is_base_of
和dynamic_cast
有不同的要求,他们的答案也可能不同。(1) 首先(正如其他人指出的那样)使用
dynamic_cast
,基类和派生类必须是多态的(必须至少有一个virtual
方法)。is_base_of
不需要类型是多态的。(2) The operands of
is_base_of
are both types whereasdynamic_cast
needs a type (inside< >
) and an object (inside( )
) .(3)
dynamic_cast
和is_base_of
可以给出不同的答案(或者一个可以编译而另一个不能编译)取决于继承的类型(public
vsprotected
或private
)。例如考虑:我们有
实际上最后一行在 GCC 中产生了一个编译器错误(
error: 'B' is an inaccessible base of 'D2'
)。 VS2010 会编译它(只产生类似于 GCC 错误消息的警告)。(4) 通过异常处理技巧可以放宽对多态类的要求。考虑:
然后我们有
值得一提的是,
is_unambiguous_public_base_of
比dynamic_cast
慢得多,并且(在下面更新中提到的重命名后,这变得更加明显)总是返回一个nullptr
的:以下链接中提供了有关此技巧的一些过时参考:
第 1 部分、 第 2 部分 和 代码
免责声明:以上
is_unambiguous_public_base_of
的实现只是一个草案,它不能正确处理const
和volatile
资格。更新:在这篇文章的前一个版本中,
is_unambiguous_public_base_of
被命名为my_dynamic_cast
这是造成混乱的根源。所以我把它重命名为一个更有意义的名字。 (感谢简赫尔曼。)