static_cast在编译时进行类型转换,适用于已知安全的转换,如数值类型转换和类的上行转型;dynamic_cast在运行时通过RTTI检查类型,用于多态类的安全向下转型,转换失败返回nullptr或抛出异常,更安全但有性能开销。

C++中进行类型转换,主要有四种显式的转换方式:
static_cast
dynamic_cast
const_cast
reinterpret_cast
static_cast
dynamic_cast
static_cast
在C++里,类型转换这回事儿,说实话,是个既强大又容易出岔子的地方。我们手里有几把不同的“锤子”,每把都有它擅长敲的“钉子”。
static_cast
int
double
class Base {
public:
void func() { /* ... */ }
};
class Derived : public Base {
public:
void derivedFunc() { /* ... */ }
};
// 示例1:基本类型转换
int i = 10;
double d = static_cast<double>(i); // 编译时安全转换
// 示例2:向上转型 (安全)
Derived* pd = new Derived();
Base* pb = static_cast<Base*>(pd); // 编译时安全转换
// 示例3:向下转型 (需要程序员保证安全)
Base* pb2 = new Derived(); // 实际是Derived对象
Derived* pd2 = static_cast<Derived*>(pb2); // 编译时通过,运行时如果pb2不是Derived类型,行为未定义!
Base* pb3 = new Base(); // 实际是Base对象
// Derived* pd3 = static_cast<Derived*>(pb3); // 编译时通过,运行时这里会出问题!pb3不是Deriveddynamic_cast
nullptr
std::bad_cast
立即学习“C++免费学习笔记(深入)”;
#include <iostream>
#include <typeinfo> // For std::bad_cast
class Base {
public:
virtual ~Base() {} // 必须有虚函数才能使用dynamic_cast
virtual void func() { std::cout << "Base::func" << std::endl; }
};
class Derived : public Base {
public:
void func() override { std::cout << "Derived::func" << std::endl; }
void derivedFunc() { std::cout << "Derived::derivedFunc" << std::endl; }
};
// 示例:dynamic_cast
Base* b1 = new Derived(); // b1实际指向Derived对象
if (Derived* d1 = dynamic_cast<Derived*>(b1)) {
d1->derivedFunc(); // 安全调用
} else {
std::cout << "Conversion failed for b1" << std::endl;
}
Base* b2 = new Base(); // b2实际指向Base对象
if (Derived* d2 = dynamic_cast<Derived*>(b2)) {
d2->derivedFunc(); // 不会执行,d2为nullptr
} else {
std::cout << "Conversion failed for b2" << std::endl; // 输出此行
}
// 引用类型的dynamic_cast
Derived obj_derived;
Base& ref_base_derived = obj_derived;
try {
Derived& ref_derived = dynamic_cast<Derived&>(ref_base_derived);
ref_derived.derivedFunc();
} catch (const std::bad_cast& e) {
std::cout << "Bad cast for ref_base_derived: " << e.what() << std::endl;
}
Base obj_base;
Base& ref_base = obj_base;
try {
Derived& ref_derived = dynamic_cast<Derived&>(ref_base); // 这里会抛出std::bad_cast
ref_derived.derivedFunc();
} catch (const std::bad_cast& e) {
std::cout << "Bad cast for ref_base: " << e.what() << std::endl; // 输出此行
}
delete b1;
delete b2;还有
const_cast
const
volatile
最后是
reinterpret_cast
static_cast
dynamic_cast
在我看来,它们最根本的区别在于“何时”以及“如何”进行类型检查。
static_cast
static_cast
而
dynamic_cast
dynamic_cast
dynamic_cast
dynamic_cast
简单来说,
static_cast
dynamic_cast
static_cast
我觉得,当你对类型转换有绝对的把握,并且这种转换在逻辑上是“自然”的时候,
static_cast
比如,你正在进行数值类型之间的转换,像把
int
float
double
int
// 示例:向上转型,使用static_cast是惯例且安全 Derived d_obj; Base* b_ptr = static_cast<Base*>(&d_obj); // 总是安全的 Base& b_ref = static_cast<Base&>(d_obj); // 总是安全的
另一个常见场景是,当你有一个
void*
static_cast
void* raw_ptr = new int(42); int* i_ptr = static_cast<int*>(raw_ptr); // 知道raw_ptr实际指向int std::cout << *i_ptr << std::endl; delete static_cast<int*>(raw_ptr); // 释放内存
此外,如果你需要显式地调用一个单参数构造函数来完成类型转换,
static_cast
static_cast
dynamic_cast
当你需要在运行时,安全地将一个基类指针或引用转换为派生类指针或引用时,
dynamic_cast
这通常发生在多态的场景中,比如你有一个基类指针,它可能指向基类对象,也可能指向任何一个派生类对象。而你现在需要调用某个派生类特有的方法。这时候,你就不能简单地用
static_cast
static_cast
dynamic_cast
nullptr
std::bad_cast
// 假设我们有一个处理基类指针的函数
void processObject(Base* obj) {
if (Derived* d_obj = dynamic_cast<Derived*>(obj)) {
// 只有当obj确实是Derived或其派生类时,这里才会被执行
d_obj->derivedFunc();
} else {
std::cout << "Object is not of type Derived." << std::endl;
obj->func(); // 调用基类方法
}
}
// 在main函数中调用
// Derived* my_derived = new Derived();
// Base* my_base = new Base();
// processObject(my_derived); // 成功转换为Derived并调用derivedFunc
// processObject(my_base); // 转换失败,调用Base::func这种运行时类型识别的能力,对于构建灵活、健壮的面向对象系统至关重要。比如,你可能有一个插件系统,所有插件都实现一个共同的接口(基类),但每个插件可能还有自己独特的子类功能。当你在运行时加载一个插件时,你需要判断它是否支持某个特定的子功能,这时
dynamic_cast
dynamic_cast
以上就是C++类型转换有哪些方式 static_cast dynamic_cast区别的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号