C++ 类型转换 包括C风格的转换、static_cast、const_cast、reinterpret_cast、dynamic_cast、模板特化等
flyfish
0. 隐式转换(Implicit Conversions)
隐式转换是编译器自动进行的类型转换,通常在需要将一个类型转换为另一个类型以匹配函数参数、赋值或比较时发生。
示例:
#include <iostream> void printInt(int i) { std::cout << "Implicitly converted to int: " << i << std::endl; } int main() { char c = 'A'; // char类型 printInt(c); // char类型隐式转换为int类型 return 0; }
在这个例子中,字符类型char
被隐式转换为整数类型int
以匹配函数参数类型。
1. C-Style Casts (C风格的转换)
C风格的转换使用括号进行类型转换。这种转换方式功能强大,但缺乏类型安全性,可能导致难以发现的错误。
示例:
#include <iostream> int main() { double d = 9.99; int i = (int)d; // C-Style Cast std::cout << "C-Style Cast: " << i << std::endl; return 0; }
2. C++风格的转换运算符
static_cast
static_cast
用于在相关类型之间进行显式转换,例如从基类指针转换为派生类指针,或者从int
转换为double
。
示例:
#include <iostream> int main() { double d = 9.99; int i = static_cast<int>(d); std::cout << "static_cast: " << i << std::endl; return 0; }
const_cast
const_cast
用于移除或添加const
属性。
移除
const
属性:使用const_cast
将const
对象转换为非const
对象,通常用于将const
对象传递给只能接受非const
对象的函数。添加
const
属性:使用const_cast
将非const
对象转换为const
对象,通常用于将非const
对象传递给只能接受const
对象的函数。
示例:
移除 const
属性的示例:
#include <iostream> // 打印非const整型值的函数 void printNonConst(int* x) { *x = 20; // 修改非const整型值 std::cout << "Modified value: " << *x << std::endl; } int main() { const int i = 10; // 定义const整型值 // 使用const_cast移除const属性 printNonConst(const_cast<int*>(&i)); return 0; }
在这个例子中,printNonConst
函数接受一个非const
的int
指针,并修改该值。我们在main
函数中定义了一个const
整型变量i
,然后使用const_cast
将其const
属性移除,以便将其传递给printNonConst
函数进行修改。
添加 const
属性的示例:
#include <iostream> // 打印const整型值的函数 void printConst(const int* x) { std::cout << "Const value: " << *x << std::endl; } int main() { int i = 10; // 定义非const整型值 // 使用const_cast添加const属性 printConst(const_cast<const int*>(&i)); return 0; }
在这个例子中,printConst
函数接受一个const
的int
指针,并打印该值。我们在main
函数中定义了一个非const
整型变量i
,然后使用const_cast
添加其const
属性,以便将其传递给printConst
函数。
reinterpret_cast
reinterpret_cast
用于转换任意类型的指针。它不会检查被转换的类型是否相关,因此需要谨慎使用。
示例:
#include <iostream> int main() { int i = 10; void* p = &i; int* ip = reinterpret_cast<int*>(p); std::cout << "reinterpret_cast: " << *ip << std::endl; return 0; }
dynamic_cast
dynamic_cast
用于在继承层次结构中进行安全的类型转换,只能用于指向多态类型的指针或引用。
示例:
#include <iostream> class Base { public: virtual ~Base() {} }; class Derived : public Base { public: void sayHello() { std::cout << "Hello from Derived" << std::endl; } }; int main() { Base* base = new Derived(); Derived* derived = dynamic_cast<Derived*>(base); if (derived) { derived->sayHello(); } else { std::cout << "dynamic_cast failed" << std::endl; } delete base; return 0; }
3. Conversion Operators (转换运算符)
从类的对象转换为指定的基本类型或其他类类型
类可以定义成员函数operator type()
,实现对象到其他类型的转换。
用户定义的转换通过构造函数和转换运算符实现,允许将类对象转换为内置类型或其他类类型。
示例:
#include <iostream> class Integer { int value; public: Integer(int v) : value(v) {} operator int() const { return value; } }; int main() { Integer integer(42); int i = integer; // 自动调用转换运算符 std::cout << "Conversion Operator: " << i << std::endl; return 0; }
4. Explicit Conversion Operators (显式转换运算符)
类似于转换运算符,但加上了explicit关键字,防止了隐式转换。这通常用于只有一个参数的转换运算符,以避免意外的类型转换
通过explicit
关键字,防止隐式转换。
示例:
#include <iostream> class Integer { int value; public: Integer(int v) : value(v) {} explicit operator int() const { return value; } }; int main() { Integer integer(42); // int i = integer; // 这行会编译错误,因为转换运算符是显式的 int i = static_cast<int>(integer); // 需要显式转换 std::cout << "Explicit Conversion Operator: " << i << std::endl; return 0; }
5. 模板特化(Template Specialization)
模板特化允许为特定类型提供定制的实现,通常用于为特定类型定制转换逻辑。
示例:
#include <iostream> template<typename T> class Converter { public: static void convert(const T& value) { std::cout << "Generic conversion: " << value << std::endl; } }; // 对int类型进行特化 template<> class Converter<int> { public: static void convert(const int& value) { std::cout << "Specialized conversion for int: " << value << std::endl; } }; int main() { Converter<double>::convert(3.14); // 使用泛型转换 Converter<int>::convert(42); // 使用特化转换 return 0; }
输出
Generic conversion: 3.14 Specialized conversion for int: 42
在这个例子中,定义了一个模板类Converter
,并对int
类型进行了特化,以提供定制的转换逻辑。