C++ 一共有4种类型转换方式,分别是: static_cast
,dynamic_cast
,const_cast
,reinterpret_cast
。
static_cast
一般有以下应用:
- 用来强迫隐式转换,如:基本数据类型之间的转换;将
void*
指针转为typed*
指针;将non-const
转为const
double i = 3.14; int j = static_cast<int>(i);
- 用于继承中:
- 上行转换:父类指针和子类指针之间的转换;将子类指针和引用转换为父类(多态),这是安全的;
- 下行转换:将父类指针和引用转换为子类,相对于下面的
dynamic_cast
来说这是不安全的。class Base { public: Base() { cout << "Base()" << endl; } virtual ~Base() { cout << "~Base()" << endl; } void Base_test() { cout << "Base::Base_test()" << endl; } virtual void vir_test() { cout << "Base::vir_test()" << endl;} }; class Derived : public Base { public: Derived() { cout << "Derived()" << endl;} virtual ~Derived() { cout << "~Derived()" << endl; } void Derived_test() { cout << "Derived::Derived_test()" << endl;} virtual void vir_test() { cout << "Derived::vir_test()" << endl;} }; // 将子类指针赋给父类指针多态正常用法(向上转型) // 将父类指针赋值给子类指针(向下转型) 使用static_cast(不安全,非常不推荐) Base base; Derived *d_ptr = static_cast<Derived*>(&base); d_ptr->Base_test(); // Base::Base_test() 可以调用父类的函数(继承) d_ptr->Derived_test(); // Derived::Derived_test 可以调用子类的新函数 d_ptr->vir_test(); // Base::vir_test() 虚函数调用正常,调用的是父类的函数
- 左值转换成右值引用
在std::move
中有这个操作,我们可以显示的将一个左值转换为一个右值引用template <typename T> typename remove_reference<T>::type&& move(T&& t) { return static_cast<typename remove_reference<T>::type&&>(t); }
dynamic_cast
上行转换和static_cast
没有区别,都是安全的;下行转换时,dynamic_cast
会做类型安全检查,父类没有虚函数时,编译会报错。
class Base
{
public:
Base() { cout << "Base()" << endl; }
~Base() { cout << "~Base()" << endl; }
void Base_test() { cout << "Base::Base_test()" << endl; }
};
class Derived : public Base
{
public:
Derived() { cout << "Derived()" << endl;}
~Derived() { cout << "~Derived()" << endl; }
void Derived_test() { cout << "Derived::Derived_test()" << endl;}
};
// 将父类指针赋值给子类指针(向下转型) 使用dynamic_cast
Base base2;
Derived *d_ptr2 = dynamic_cast<Derived*>(&base2); // 编译报错
const_cast
const_cast
用于移除类型的 const
、volatile
和 __unaligned
属性。
const char *words = "hello world";
char *p = const_cast<char*>(words);
reinterpret_cast
reinterpret_cast
用来执行低级转换,在编译期完成,可以转换任何类型的指针,比如将一个int*
转为int
,极不安全,不推荐使用。