在C++中,类的类型转换可以分为两种:隐式类型转换和显式类型转换。C++11标准引入了四个关键字来控制这两种类型转换:static_cast
、dynamic_cast
、const_cast
和 reinterpret_cast
。在介绍这些转换之前,我们先来看一下隐式类型转换。
隐式类型转换
隐式类型转换是自动发生的,不需要程序员显式地指定。在C++中,隐式类型转换可以通过构造函数、类型转换运算符和用户定义的类型转换来实现。
构造函数
当类的构造函数接受一个参数时,编译器会自动使用这个构造函数来进行类型转换。例如:
class MyClass {
public:
MyClass(int value) : m_value(value) {}
private:
int m_value;
};
MyClass obj = 42; // 隐式类型转换,调用MyClass(int)构造函数
类型转换运算符
类型转换运算符允许类的一个对象被转换为另一种类型。定义类型转换运算符时,需要使用 operator
关键字后跟目标类型。例如:
class MyClass {
public:
MyClass(int value) : m_value(value) {}
operator int() const { return m_value; } // 类型转换运算符
private:
int m_value;
};
MyClass obj(42);
int value = obj; // 隐式类型转换,调用operator int()运算符
用户定义的类型转换
C++11引入了显式的类型转换运算符,通过在类型转换运算符前加上 explicit
关键字,可以阻止编译器进行隐式类型转换,但仍然允许显式类型转换。例如:
class MyClass {
public:
explicit MyClass(int value) : m_value(value) {}
explicit operator int() const { return m_value; } // 显式的类型转换运算符
private:
int m_value;
};
MyClass obj(42);
// int value = obj; // 错误,不允许隐式类型转换
int value = static_cast<int>(obj); // 正确,显式类型转换
显式类型转换
显式类型转换需要程序员明确指示,使用 static_cast
、dynamic_cast
、const_cast
和 reinterpret_cast
四个关键字之一。
static_cast
static_cast
用于执行静态类型转换,它可以用于执行基本数据类型之间的转换,也可以用于类层次结构中上下转换(只要没有虚继承)。例如:
double pi = 3.14159;
int integer_pi = static_cast<int>(pi); // 浮点数转整数
dynamic_cast
dynamic_cast
用于执行动态类型转换,它主要用于类层次结构中的向下转换(从基类指针或引用转换到派生类指针或引用)。它会在运行时检查类型是否正确。例如:
Base* base = new Derived();
Derived* derived = dynamic_cast<Derived*>(base); // 基类指针转派生类指针
const_cast
const_cast
用于去除或添加 const
特性。例如:
const char* str = "Hello, World!";
char* non_const_str = const_cast<char*>(str); // 去除const
reinterpret_cast
reinterpret_cast
用于执行低级转换,它可以将指针转换为其他类型的指针,或者将整数转换为指针,等等。这种转换是非常危险的,因为它忽略了类型之间的差异,可能会导致未定义的行为。例如:
int value = 42;
int* ptr = &value;
void* void_ptr = reinterpret_cast<void*>(ptr); // 整型指针转void指针
在使用这些显式类型转换时,程序员需要确保转换的安全性,避免未定义行为的发生。