正则表达式vs. static_cast与dynamic_cast [英] Regular cast vs. static_cast vs. dynamic_cast

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

问题描述

我已经写了C和C ++代码了近二十年,但这些语言有一个方面我从来没有真正理解。我明显使用常规cast。即

  MyClass * m =(MyClass *)ptr; 

,但似乎还有其他两种类型的演员,知道差异。下面的代码行有什么区别?

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


解决方案

static_cast



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

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

int main(){
MyClass c;
start_thread(& func,& c)// func(& c)将被称为
.join();
}



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



dynamic_cast



dynamic_cast 用于不知道对象的动态类型的情况。如果你向下转换并且参数类型不是多态的,你不能使用 dynamic_cast 。例如:

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

dynamic_cast 返回一个空指针,如果引用的对象不包含类型cast作为基类(当你转换为引用时,在这种情况下引发 bad_cast 异常)。



以下代码无效,因为 Base 不是多态的(不包含虚拟函数):

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

up-cast c $ c> static_cast 和 dynamic_cast ,也没有任何转换,因为up-cast是一个隐式转换。

常规演员



这些演员也称为C风格演员。 C风格的转换基本上与尝试一系列C ++转换序列相同,并采用第一个C ++转换,而不考虑 dynamic_cast 。不用说,这是更强大的,因为它结合了所有 const_cast static_cast reinterpret_cast ,但它也不安全,因为它不使用 dynamic_cast



此外,C风格的转换不仅允许你这样做,但它们也允许你安全地转换为一个私有的基类,而等价的 static_cast 序列给你一个编译时错误。



有些人喜欢C风格的cast,因为他们的简洁。我只使用它们进行数值转换,并且在涉及用户定义的类型时使用适当的C ++转换,因为它们提供了更严格的检查。


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 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();
}

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.

dynamic_cast

dynamic_cast is used for cases where you don't know what the dynamic type of the object is. You cannot use dynamic_cast if you downcast and the argument type is not polymorphic. An example:

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

dynamic_cast returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a bad_cast exception is thrown in that case).

The following code is not valid, because Base is not polymorphic (it doesn't contain a virtual function):

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

An "up-cast" is always valid with both static_cast and dynamic_cast, and also without any cast, as an "up-cast" is an implicit conversion.

Regular 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.

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.

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与dynamic_cast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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