本篇内容主要讲解“C++怎么使用dynamic_cast”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++怎么使用dynamic_cast”吧!
dynamic_cast会在运行时检查。
Example(示例)
struct B { // an interface
virtual void f();
virtual void g();
virtual ~B();
};
struct D : B { // a wider interface
void f() override;
virtual void h();
};
void user(B* pb)
{
if (D* pd = dynamic_cast<D*>(pb)) {
// ... use D's interface ...
}
else {
// ... make do with B's interface ...
}
}
使用其他的类型转换无法保证类型安全并导致程序将一个实际上是类型X的变量当成类型Z访问。
void user2(B* pb) // bad
{
D* pd = static_cast<D*>(pb); // I know that pb really points to a D; trust me
// ... use D's interface ...
}
void user3(B* pb) // unsafe
{
if (some_condition) {
D* pd = static_cast<D*>(pb); // I know that pb really points to a D; trust me
// ... use D's interface ...
}
else {
// ... make do with B's interface ...
}
}
void f()
{
B b;
user(&b); // OK
user2(&b); // bad error
user3(&b); // OK *if* the programmer got the some_condition check right
}
向其他类型转换一样,dynamic_cast也被过度使用了。更应该使用虚函数而不是类型转换。在继承体系中移动时如果可能(不需要执行时决定)而且更便利的话应该利用静态多态机制。
有些人在typeid更合适的时候使用dynamic_cast; dyamic_cast只是一个为了发现对象的最优接口而使用的判断"是某种类型"的通常操作。而typeid是”告诉我对象的实际类型"的操作,用于得到对象的类型。后者一定会更简单,也应该是更快的操作。如果有必要的话,后者(typeid)更容易自己实现(例如,如果由于某种原因,工作的系统禁止使用RTTI),一般来讲,前者(dynamic_cast)的正确实现要困难得多。
Consider(考虑):
struct B {
const char* name {"B"};
// if pb1->id() == pb2->id() *pb1 is the same type as *pb2
virtual const char* id() const { return name; }
// ...
};
struct D : B {
const char* name {"D"};
const char* id() const override { return name; }
// ...
};
void use()
{
B* pb1 = new B;
B* pb2 = new D;
cout << pb1->id(); // "B"
cout << pb2->id(); // "D"
if (pb1->id() == "D") { // looks innocent
D* pd = static_cast<D*>(pb1);
// ...
}
// ...
}
pb2->id() == "D"的结果实际上是实现决定的。我们将它加进来是为了警示自制RTTI的危险性。这段代码可能会如愿工作很多年,只是到了一个没有统一字符字面量的新机器,新编译器或者新连接器时会失败。
如果以自己实现RTTI,要小心。
如果你的实现提供了一个真的很慢的dynamic_cast,你也许必须变通。然而,所有的变通都无法静态解决而且容易发生错误,包括显示类型转换(通常是static_cast)。你只能设计出用于特殊目的的dynamic_cast。因此,首先确认你的dynamic_cast真的像你想的那么慢(关于这件事存在一些未经证实的谣言)并且你使用dynamic_cast的地方对性能是否真的那么敏感。
我们认为目前dynamic_cast的实现有些不必要地慢了。例如,在合适的条件下,dynamic_cast可以在很短的固定时间内完成。然而,兼容性使变更很困难,即使所有人都同意优化的有价值的。
存在非常罕见的情况,如果你已经判定dynamic_cast的影响是确实存在的,你可以使用其他的方式静态保证向下转换会成功(例如,你小心地使用了CRTP),而且不涉及到虚继承的话,可以考虑战术上采用带有明显注释的static_cast。但是由于类型系统不能进行正确性验证,需要对这段代码进行免责声明,并且进行认为提醒。即使做到这种程度,在我们的经验中,像这样“我知道我在做什么"的情况仍然是一个有名的错误源。
Exception(例外)
Consider(考虑如下代码):
template<typename B>
class Dx : B {
// ...
};
指出使用static_cast实现向下转换的情况,包括执行static_cast的C风格转换。
本规则也是类型安全规则群的内容
到此,相信大家对“C++怎么使用dynamic_cast”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。