You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

派生类错误向下转型导致运行时异常问题求助

问题分析与解决建议

你的代码触发std::__non_rtti_object异常的核心原因是野指针访问,具体问题出在construct函数中:

da_vec.push_back(std::unique_ptr<derivedA>(new derivedB(4)).get());

这里的std::unique_ptr是临时对象,当这条语句执行完毕后,临时unique_ptr会被销毁,同时自动释放它管理的derivedB对象。但你把get()返回的裸指针存入了vector,导致vector里的指针变成悬空指针(指向已被释放的内存)。后续在func中对这个悬空指针的引用做dynamic_cast时,因为对象已不存在,RTTI信息无法正常获取,进而触发该异常。

解决方法

方法1:改用智能指针容器存储(推荐)

直接使用std::vector<std::unique_ptr<derivedA>>管理对象,避免手动内存管理风险:

#include <iostream>
#include <vector>
#include <memory>

class Base {
public:
    int a;
    Base(int _a) : a(_a) {};
    virtual void print() = 0;
};

class derivedA : public Base
{
public:
    derivedA(int _a) : Base(_a) {};
    void print() { std::cout << "dA" << std::endl; }
};

class derivedB : public derivedA
{
public:
    derivedB(int _a) : derivedA(_a) {};
    void print() { std::cout << "dB" << std::endl; }
};

void construct(std::vector<std::unique_ptr<derivedA>>& da_vec) {
    da_vec.push_back(std::make_unique<derivedB>(4));
}

void func(derivedA& da)
{
    // 用指针版dynamic_cast判断转换是否成功,避免抛出异常
    if (derivedB* db_ptr = dynamic_cast<derivedB*>(&da)) {
        db_ptr->print();
    } else {
        std::cout << "转换为derivedB失败" << std::endl;
    }
}

int main()
{
    std::vector<std::unique_ptr<derivedA>> da_vec;
    construct(da_vec);
    for (auto& da : da_vec)
        func(*da);
}

通过std::make_unique创建智能指针并直接存入容器,确保对象生命周期由智能指针自动管理,不会出现悬空指针问题。同时改用指针版dynamic_cast,可以提前判断转换是否成功,避免转换失败时抛出std::bad_cast异常。

方法2:手动管理内存(不推荐,易出错)

如果必须使用裸指针容器,需手动控制内存生命周期,避免临时智能指针销毁对象:

void construct(std::vector<derivedA*>& da_vec) {
    // 直接new对象,不通过临时unique_ptr,后续需手动释放
    da_vec.push_back(new derivedB(4));
}

int main()
{
    std::vector<derivedA*> da_vec;
    construct(da_vec);
    for (auto& da : da_vec)
        func(*da);
    // 手动释放所有对象,避免内存泄漏
    for (auto da : da_vec) {
        delete da;
    }
}

这种方法需要严格把控内存的创建与释放时机,容易因遗漏delete导致内存泄漏,或提前释放导致悬空指针,因此不推荐使用。

内容的提问来源于stack exchange,提问作者H'H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:45:20