常规转换 vs. static_cast vs. dynamic_cast [英] Regular cast vs. static_cast vs. dynamic_cast

查看:26
本文介绍了常规转换 vs. static_cast vs. dynamic_cast的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写 C 和 C++ 代码将近 20 年了,但我从未真正理解这些语言的一个方面.我显然使用了常规演员,即

I've been writing C and C++ code for almost twenty years, but there's one aspect of these languages that I've never really understood. I've obviously used regular casts i.e.

MyClass *m = (MyClass *)ptr;

到处都是,但似乎还有另外两种类型的演员表,我不知道有什么区别.下面几行代码有什么区别?

all over the place, but there seem to be two other types of casts, and I don't know the difference. What's the difference between the following lines of code?

MyClass *m = (MyClass *)ptr;
MyClass *m = static_cast<MyClass *>(ptr);
MyClass *m = dynamic_cast<MyClass *>(ptr);

推荐答案

static_cast

`static_cast` 用于您基本上想要反转隐式转换的情况,有一些限制和添加.`static_cast` 不执行运行时检查.如果您知道您引用了特定类型的对象,则应该使用它,因此无需检查.例子:

static_cast

`static_cast` is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. `static_cast` performs no runtime checks. This should be used if you know that you refer to an object of a specific type, and thus a check would be unnecessary. Example:

void func(void *data) {
  // Conversion from MyClass* -> void* is implicit
  MyClass *c = static_cast<MyClass*>(data);
  ...
}

int main() {
  MyClass c;
  start_thread(&func, &c)  // func(&c) will be called
      .join();
}

在这个例子中,你知道你传递了一个 MyClass 对象,因此不需要运行时检查来确保这一点.

In this example, you know that you passed a MyClass object, and thus there isn't any need for a runtime check to ensure this.

if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
  ...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
  ...
}

如果向下转换(转换为派生类)并且参数类型不是多态的,则不能使用 dynamic_cast.例如,以下代码无效,因为 Base 不包含任何虚函数:

You cannot use dynamic_cast if you downcast (cast to a derived class) and the argument type is not polymorphic. For example, the following code is not valid, because Base doesn't contain any virtual function:

struct Base { };
struct Derived : Base { };
int main() {
  Derived d; Base *b = &d;
  dynamic_cast<Derived*>(b); // Invalid
}

向上投射"(cast to the base class) 对于 static_castdynamic_cast 总是有效的,也没有任何强制转换,作为向上转换"是一个隐式转换(假设基类是可访问的,即它是一个 public 继承).

An "up-cast" (cast to the base class) is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion (assuming the base class is accessible, i.e. it's a public inheritance).

这些类型转换也称为 C 风格类型转换.C 风格的强制转换基本上等同于尝试一系列 C++ 强制转换,并采用第一个有效的 C++ 强制转换,而无需考虑 dynamic_cast.不用说,这更强大,因为它结合了所有 const_caststatic_castreinterpret_cast,但它也不安全,因为它不使用 dynamic_cast.

These casts are also called C-style cast. A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works, without ever considering dynamic_cast. Needless to say, this is much more powerful as it combines all of const_cast, static_cast and reinterpret_cast, but it's also unsafe, because it does not use dynamic_cast.

此外,C 风格的强制转换不仅允许您执行此操作,而且还允许您安全地强制转换为私有基类,而等效的"则是static_cast 序列会给你一个编译时错误.

In addition, C-style casts not only allow you to do this, but they also allow you to safely cast to a private base-class, while the "equivalent" static_cast sequence would give you a compile-time error for that.

有些人更喜欢 C 风格的类型转换,因为它们很简洁.我仅将它们用于数字转换,并在涉及用户定义的类型时使用适当的 C++ 转换,因为它们提供更严格的检查.

Some people prefer C-style casts because of their brevity. I use them for numeric casts only, and use the appropriate C++ casts when user defined types are involved, as they provide stricter checking.

这篇关于常规转换 vs. static_cast vs. dynamic_cast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆