C++ V型转换:如何将std::vector<Base1*>安全转换为std::vector<Base2*>
实现方案
前置修正
你当前给出的Derived类对Base2是默认private继承,类外无法访问父类接口也无法完成转换,同时类成员默认是private权限,需要先做如下修正:
// 补全基类析构实现,避免链接错误 Base1::~Base1() = default; Base2::~Base2() = default; // 修改继承权限和成员权限 class Derived: public Base1, public Base2{ public: ~Derived() override = default; void do_sth() override { // 需包含<cstdio>使用printf,原代码print为笔误 printf("Hi"); }; };
转换实现
std::vector<Base1*>和std::vector<Base2*>是完全不相关的容器类型,无法直接整体转换,需要逐个处理容器内的指针,全程仅拷贝指针值,不会产生对象拷贝:
int main() { std::vector<Base1*> vec1; vec1.reserve(10); for( int i = 0; i < 10; ++i ) { vec1.push_back(new Derived()); } std::vector<Base2*> vec2; vec2.reserve(vec1.size()); for (auto base1_ptr : vec1) { // dynamic_cast做运行时类型安全检查,Base1为多态类型符合转换要求 Derived* derived_ptr = dynamic_cast<Derived*>(base1_ptr); if (derived_ptr != nullptr) { // Derived*可隐式转换为Base2*,无需额外显式转换 vec2.push_back(derived_ptr); } else { // 可自行添加转换失败的业务处理逻辑 } } // 若要转移内存所有权,转换完成后清空vec1即可,避免重复释放 vec1.clear(); // 测试验证:访问Base2的成员属性 for (auto base2_ptr : vec2) { printf("%d\n", base2_ptr->prop); // 输出3 } // 销毁对象避免内存泄漏 for (auto base2_ptr : vec2) { delete base2_ptr; } vec2.clear(); return 0; }
关键说明
- 安全转换保证:
dynamic_cast会在运行时检查Base1*指向的实际类型是否为Derived,如果不是会返回nullptr,避免非法内存访问。 - 无对象拷贝:整个过程仅复制指针的地址值,所有指针指向的还是原来创建的
Derived对象,没有触发任何对象拷贝构造或移动逻辑。 - 内存所有权处理:如果需要转移所有权,转换后清空
vec1即可,后续对象的生命周期由vec2的指针负责管理,销毁时只需要遍历vec2释放一次内存即可,不会出现重复释放问题。如果不需要转移,两个容器可以同时持有指向同个对象的指针,注意不要重复释放即可。
内容的提问来源于stack exchange,提问作者ibarrond
相关产品推荐
相关产品推荐

