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

程序未进入虚析构函数:继承std::string的多态问题问询

为什么继承std::string后delete基类指针会导致程序卡住?

这个问题的核心其实踩中了C++标准库类设计的一个关键细节——std::string的析构函数不是虚函数,这直接导致了你遇到的未定义行为。咱们一步步拆解:

  • 问题根源:非虚析构的基类无法触发多态析构
    C++规定,当你通过基类指针删除派生类对象时,只有基类的析构函数是虚函数,才会按照多态规则调用派生类的析构函数,完成整个对象的正确销毁。而std::string的析构函数是非虚的——标准库的容器、字符串这类类从设计上就没打算被当作基类继承,所以不会为了多态付出虚表指针的内存开销。

  • 你的代码执行流程问题
    你写的string *s = new MyClass();是基类指针指向派生类对象,当执行delete s;时,编译器只会调用std::string的析构函数,完全不会触发MyClass的虚析构。虽然你的MyClass没有额外成员变量,但因为声明了虚析构,对象内存布局里会包含一个虚表指针。这部分属于MyClass的内容没有被正确销毁,直接引发了未定义行为——程序卡住只是这种行为的一种表现,它也可能崩溃、输出乱码,甚至看似正常运行,这些都是未定义行为的不确定性。

  • 怎么修复?
    最合理的方案是不要继承std::string,如果需要扩展字符串功能,更推荐用组合(比如在MyClass里放一个std::string成员)而不是继承。如果一定要保持继承的写法(非常不推荐,违反标准库类的设计意图),那必须用派生类指针来删除对象:

    MyClass *s = new MyClass();
    delete s; // 这时候会正确调用MyClass的虚析构,再调用std::string的析构
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:52:40