C++中的静态转换– static_cast()方法

时间:2020-02-23 14:30:05  来源:igfitidea点击:

在本文中,我们将介绍如何在现代C++中使用Static Cast函数。
我们还将解决与其他类型的演员相关的一些差异。

对于许多具有C背景的程序员来说,这可能是一个棘手的话题。

在C++中,执行隐式或者显式类型转换的方法有多种,并且使用诸如static_cast(),dynamic_cast(),reinterpret_cast()等函数,很容易造成混淆。

了解static_cast()

如果您要执行基于编译时(静态)推断的任何类型的转换,这就是方法。

我们可以使用" static_cast()"执行常见的C型转换,例如将" int"转换为" float",反之亦然。
同样,我们也可以在指针和引用之间进行转换。

new_type value = static_cast <new_type> (expression);

强制转换"表达式"后,这将返回类型" new_type"的值。

例如,如果要将包含整数和浮点数的算术表达式转换为" float",则可以执行以下操作:

#include <iostream>

using namespace std;

int main() {
  int a = 5;
  float b = 20.5;
  
  float result = static_cast<float>(a + b);
  cout << result << endl;
  return 0;
}

输出

25.5

实际上,如上所述,我们的输出已静态转换为" float"。

我们还可以将指针转换为" void *"之类的指针。

#include <iostream>

template <class T>
bool isVoid(T *t) { return false;  } //normal case returns false 

template <>
bool isVoid(void *t) { return true; }  //but for void* returns true

using namespace std;

int main() {
  //Use a C-style cast to convert a string constant to a char*
  char* arr = (char*)"Hello from theitroad";
  //Use static_cast() to convert to a void* pointer
  void* ptr = static_cast<void*>(arr);
  cout << "Is this a void* ptr? " << (isVoid(ptr) ? "Yes" : "No") << endl;
  //Convert back to char*
  cout << static_cast<char*>(ptr) << endl;
  return 0;
}

输出

Is this a void* ptr? Yes
Hello from theitroad

我们使用模板函数" isVoid()"来检查传递给它的指针是否为" void *"。
观察到" static_cast()"能够将指针静态转换为任何特定类型。

" static_cast()"确保所有强制转换都在编译时执行,因此,与" dynamic_cast()"之类的其他强制转换不同,此函数没有运行时开销。

通过继承进行转换

如果派生类是公开继承的,我们还可以使用" static_cast()"通过继承来进行强制转换。

考虑下面的代码片段。

#include <iostream>

using namespace std;

class BaseClass {
  public:
      int a, b;
      BaseClass(int val_a = 200, int val_b = 200) { 
      a = val_a; b = val_b; 
      }
      void print_obj() {
      cout<<"BaseClass Object: a = "<< a <<" , b = " <<b<< endl;
      }
      ~BaseClass() {
      }
};

//We can cast only if the inheritance is public
class DerivedClass : public BaseClass {
  public:
      int c;
      DerivedClass(int val_c = 100) { c = val_c; }
      void print_obj() {
          cout << "DerivedClass Object: a = " << a << " , b = " << b << " , c = " << c << endl; 
      }
      ~DerivedClass() {
      }
};

int main() {
  //We can only cast through inheritance if we use pointers
  //Otherwise, you need to construct the type conversion methods yourself
  BaseClass* base_obj = new BaseClass(20, 25);
  DerivedClass* derived_obj = new DerivedClass(10);

  base_obj->print_obj();
  derived_obj->print_obj();

  //Cast downwards - Can do this only if you don't use Virtual Inheritance
  DerivedClass* base_to_derived = static_cast<DerivedClass*>(base_obj);
  cout << "After casting BaseClass object to DerivedClass, ";
  base_to_derived->print_obj();

  //Can cast upwards - Redundant
  BaseClass* derived_to_base = static_cast<BaseClass*>(derived_obj);
  cout << "After casting DerivedClass object to BaseClass, ";
  derived_to_base->print_obj();

  //Free the pointers
  delete base_obj;
  delete derived_obj;

  return 0;
}

其中我们可以使用static_cast <DerivedClass *>()从基类到派生类执行指针转换。
您只能对指针执行此操作,而不能对对象本身执行此操作。

我们也可以做相反的事情,但是由于继承,演员表是多余的。

输出

BaseClass Object: a = 20 , b = 25
DerivedClass Object: a = 200 , b = 200 , c = 10
After casting BaseClass object to DerivedClass, DerivedClass Object: a = 20 , b = 25 , c = 0
After casting DerivedClass object to BaseClass, BaseClass Object: a = 200 , b = 200

确实,我们已经可以使用static_cast &lt;>()成功进行了投射,而这在运行时无需另外花费!

因此,仅当您要在原始类型之间进行类型转换或者通过继承进行简单类型转换时,才使用静态类型转换。
否则,最好使用诸如dynamic_cast <>()之类的强制类型转换。