static_cast - 兼容类型之间的转换是什么意思? [英] static_cast - what does conversion between compatible types mean?

查看:110
本文介绍了static_cast - 兼容类型之间的转换是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道static_cast可以在base和derived之间以及derived和base之间进行转换。 dynamic_cast将检查生成的对象是一个完整对象。

I understand that static_cast can convert between base and derived and between derived and base. dynamic_cast will check resulting object is a 'complete' object.

dynamic_cast使用RTTI功能。但static_cast如何工作? 兼容类型是什么意思?

dynamic_cast uses RTTI feature. But how does static_cast work? What does 'compatible types' mean?

我的问题是什么是兼容类型的意思。但我很高兴,从岗位上学到了东西。此示例演示了编译器如何解释兼容类型。最后几行是最有趣的。注意有趣的结果。

My question was really about what compatible types meant. But I am happy that have learnt something from posts. This sample demonstrates how the compiler interprets compatible types. Last few lines are most interesting. note interesting results.

#include <iostream>
#include <exception>
using namespace std;

class CBase { virtual void dummy() {} };
class CDerived: public CBase {  public: CDerived() : a(20) {} int a; };
class CDerived2: public CBase { public: CDerived2() : b(7) {} int b; };
class CDerived3: public CBase { public: CDerived3() : c('A') {} char c; };
class CNotDerived { int doit() const { return 9; } };

int main () {
  try {
      CBase * pba = new CDerived;
      CBase * pbb = new CBase;
      CDerived * pd;
      CNotDerived* pnot = new CNotDerived;
      CDerived2* pd2 = 0; 
      CDerived2* pdx = new CDerived2;
      CDerived3* pd3 = 0;


      pd = dynamic_cast<CDerived*>(pba);
      if (pd==0) cout << "Null pointer on first type-cast" << endl;   //ok

      pd = dynamic_cast<CDerived*>(pbb);
      if (pd==0) cout << "Null pointer on second type-cast" << endl;  //null ptr here

      pd = static_cast<CDerived*>(pbb);  //non-null pointer returned (not really what you want)
      if (pd==0) cout << "Null pointer on third type-cast" << endl;

// pd = dynamic_cast(pnot); //错误C2683:'dynamic_cast':'CNotDerived'不是多态类型
// if(pnot == 0)cout< Null pointer on fourth type-cast<< endl

// pd = dynamic_cast(pnot); //error C2683: 'dynamic_cast' : 'CNotDerived' is not a polymorphic type // if (pnot==0) cout << "Null pointer on fourth type-cast" << endl;

// pd = static_cast(pnot); //错误C2440:'static_cast':不能从'CNotDerived *'转换为'CDerived *'
// if(pnot == 0)cout < Null pointer on fourth type-cast<< endl;

// pd = static_cast(pnot); //error C2440: 'static_cast' : cannot convert from 'CNotDerived *' to 'CDerived *' // if (pnot==0) cout << "Null pointer on fourth type-cast" << endl;

      //below lines compiled with ms vs2008 - I believe compiler SHOULD have flagged below as an error - but did not.
      pd2 = static_cast<CDerived2*>(pba); //compiles ok but obviously incorrect
      if (pd2==0) cout << "Null pointer on fourth type-cast" << endl;
      cout << pd2->b << endl;  //compiler had decided to give us CDerived->a value! Incorrect.

      pd2 = static_cast<CDerived2*>(pdx); //compiles ok 
      if (pd2==0) cout << "Null pointer on fourth type-cast" << endl;
      cout << pd2->b << endl;  //gives correct value for b (7)

      pd3 = static_cast<CDerived2*>(pdx); //error C2440: '=' : cannot convert from 'CDerived2 *' to 'CDerived3 *'
      if (pd3==0) cout << "Null pointer on fourth type-cast" << endl;
      cout << pd3->c << endl; 

  } catch (exception& e) {
      cout << "Exception: " << e.what();
  }
  return 0;
}


推荐答案

父子关系或都是内置数字类型。它也有效,如果一个对象可以从其他对象构造,整数类型可以转换为枚举类型,void指针可以转换为指针到对象。

The main cases are they have a parent-child relationship or are both builtin numeric types. It's also valid if one object can be constructed from the other, integral types can be converted to enumerated types, and void pointers can be cast to pointer-to-object.

编辑主要情况(我省略一些更模糊的情况,例如指针到成员转换):

EDIT for the main cases (I omitted some more obscure cases like pointer-to-member casts):

5.2.9 / 2:

5.2.9/2:


如果声明T t(e);,则可以使用static_cast(e)形式的
static_cast将表达式e显式转换为类型T;对于一些发明的临时变量t(8.5),
是完好的。

An expression e can be explicitly converted to a type T using a static_cast of the form static_cast(e) if the declaration "T t(e);" is wellformed, for some invented temporary variable t (8.5).

5.2.9 / 4:

5.2.9/4:


任何表达式都可以显式转换为类型cv void。
表达式值将被丢弃。

Any expression can be explicitly converted to type "cv void." The expression value is discarded.

5.2.9 / 5:

5.2.9/5:


类型为cv1 B ,其中B是类类型,可以转换为
类型reference to cv2 D,其中D是从
B中派生的一个类(第10节),如果从pointer D到指向
B的指针存在(4.10),cv2是与c相同的cvqualification,或者更大的
cvqualification,而c不是D的虚拟基类。

An lvalue of type "cv1 B", where B is a class type, can be cast to type "reference to cv2 D", where D is a class derived (clause 10) from B, if a valid standard conversion from "pointer to D" to "pointer to B" exists (4.10), cv2 is the same cvqualification as, or greater cvqualification than, cv1, and B is not a virtual base class of D.

7.2.9 / 7:

7.2.9/7:


整数类型可以显式转换为枚举
类型。

A value of integral type can be explicitly converted to an enumeration type.

7.2.9 / 10:

7.2.9/10:


类型指向cv void的指针的右值可以显式转换为
a指向对象类型的指针。

An rvalue of type "pointer to cv void" can be explicitly converted to a pointer to object type.

这篇关于static_cast - 兼容类型之间的转换是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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