一、 std::dynamic_pointer_cast
1、用途与意义:
- 用于在继承体系中进行类型转换,支持多态。
- 它使用运行时类型识别(RTTI),在转换时会进行类型检查。只有当目标类型是源类型的实际派生类型时,转换才会成功。如果转换不合法,返回 nullptr。
- 适用于类层次结构中的智能指针转换,尤其是父类和子类之间的转换。
2、用法:
std::shared_ptr<Derived> derivedPtr = std::dynamic_pointer_cast<Derived>(basePtr);
3、示例程序:
#include <iostream>
#include <memory>class Base {
public:virtual ~Base() = default; virtual void show() const { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() const override { std::cout << "Derived class" << std::endl; }
};int main() {std::shared_ptr<Base> basePtr = std::make_shared<Derived>();std::shared_ptr<Derived> derivedPtr = std::dynamic_pointer_cast<Derived>(basePtr);if (derivedPtr) {derivedPtr->show(); } else {std::cout << "Conversion failed!" << std::endl;}return 0;
}
4、输出:
Derived class
5、说明:
- std::dynamic_pointer_cast 会尝试将 basePtr(类型为 std::shared_ptr)转换为 std::shared_ptr。如果成功,返回指向 Derived 对象的智能指针,否则返回空指针。
二、std::static_pointer_cast
1、用途与意义:
- 用于在类层次结构中进行类型转换,但转换过程是编译时检查的,不涉及运行时类型识别。
- 适用于静态类型转换,比如从基类指针到派生类指针,或者对已知类型进行转换。对于没有多态的类或已经明确知道转换合法时使用。
2、用法:
std::shared_ptr<Derived> derivedPtr = std::static_pointer_cast<Derived>(basePtr);
3、示例程序:
#include <iostream>
#include <memory>class Base {
public:virtual void show() const { std::cout << "Base class" << std::endl; }
};class Derived : public Base {
public:void show() const override { std::cout << "Derived class" << std::endl; }
};int main() {std::shared_ptr<Base> basePtr = std::make_shared<Derived>();std::shared_ptr<Derived> derivedPtr = std::static_pointer_cast<Derived>(basePtr);derivedPtr->show(); return 0;
}
4、输出:
Derived class
5、说明:
- std::static_pointer_cast 是在编译时检查类型的,适用于已知类型转换。这里,basePtr 确实指向一个 Derived 对象,因此转换是合法的。
三、std::reinterpret_pointer_cast
1、用途与意义:
- 用于进行类型间的强制转换,允许在不考虑类层次结构的情况下转换不同类型的指针。
- 这种转换是非常低级的,通常用于特殊情况,比如类型不匹配但你确信转换是安全的时。它不进行任何类型检查,因此需要特别小心使用。
2、用法:
std::shared_ptr<Derived> derivedPtr = std::reinterpret_pointer_cast<Derived>(basePtr);
3、示例程序
#include <iostream>
#include <memory>class Base {
public:virtual void show() const { std::cout << "Base class" << std::endl; }
};class Derived {
public:void display() const { std::cout << "Derived class" << std::endl; }
};int main() {std::shared_ptr<Base> basePtr = std::make_shared<Base>();std::shared_ptr<Derived> derivedPtr = std::reinterpret_pointer_cast<Derived>(basePtr);derivedPtr->display(); return 0;
}
4、输出
Derived class
5、说明:
- std::reinterpret_pointer_cast 直接将 std::shared_ptr 强制转换为 std::shared_ptr,即使它们之间没有继承关系。需要谨慎使用此方法,因为它绕过了类型检查。
四、总结与对比
转换方法 | 使用场景 | 类型检查 | 示例 |
---|
std::dynamic_pointer_cast | 用于多态类之间的类型转换,支持运行时检查 | 运行时检查 | 从基类指针转换为派生类指针 |
std::static_pointer_cast | 用于已知类型之间的转换,或类间的静态类型转换 | 编译时检查 | 基类指针到派生类指针的转换(已知转换合法) |
std::reinterpret_pointer_cast | 强制转换,不做类型检查,适用于不相关类型间的转换 | 无检查 | 强制转换不同类型的指针 |
建议:
- 如果需要在继承体系中进行类型转换,推荐使用 std::dynamic_pointer_cast,它提供了安全的类型转换检查。
- 如果你确信转换是合法的且类型之间有直接的关系,可以使用 std::static_pointer_cast。
- 对于没有类型关系的强制转换,应避免使用 std::reinterpret_pointer_cast,除非你非常清楚转换的目的和后果。