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

C++扩展std::string等内置类时父类原生方法失效如何解决?

问题原因分析

你的猜测是正确的,问题确实出在构造函数的实现上,本质是继承了std::string后没有正确初始化父类对象,仅给子类新增的独立成员s赋值,父类的实际存储内容始终是空串:

  • 你定义的str类同时持有两个string存储:一个是继承自父类std::string的内置存储,另一个是你自定义的子类成员s
  • 你在构造函数中仅给子类自定义的s赋值,继承得到的父类string部分走的是无参默认构造,内容为空
  • 调用s.size()时实际调用的是父类std::string的size()方法,读取的是父类空串的长度,自然返回0
解决方案

方案1:保留继承写法,正确初始化父类

删掉子类多余的自定义成员s,直接复用继承自父类的存储,通过构造函数初始化列表调用父类的构造函数完成赋值即可,示例代码如下:

#include <iostream>
#include <string>
using namespace std;

class str : public string {
public:
    // 初始化列表调用父类std::string的构造函数
    str(const string& s1) : string(s1) {}
    
    // 可在此处添加你的自定义方法,示例为转大写
    void to_upper() {
        for (auto& c : *this) c = toupper(c);
    }
};

int main() {
    str s("hello world");
    cout << s.size() << endl; // 正确输出11
    s.to_upper();
    cout << s << endl; // 输出HELLO WORLD
    return 0;
}

注意:std::string的析构函数不是虚函数,如果你后续存在用父类指针指向子类对象、再通过父类指针销毁对象的用法,会出现内存泄漏风险,该方案仅适合确定不会出现这类用法的场景。

方案2:改用组合实现(更安全)

如果要规避虚析构带来的风险,更推荐用组合而非继承的方式实现自定义字符串类,按需封装原生方法和自定义方法即可:

#include <iostream>
#include <string>
using namespace std;

class str {
private:
    string s; // 用组合的方式持有std::string成员
public:
    str(const string& s1) : s(s1) {}
    
    // 封装需要用到的std::string原生方法
    size_t size() const {
        return s.size();
    }
    // 重载输出运算符
    friend ostream& operator<<(ostream& os, const str& obj) {
        os << obj.s;
        return os;
    }
    
    // 自定义方法
    void to_upper() {
        for (auto& c : s) c = toupper(c);
    }
};

int main() {
    str s("hello world");
    cout << s.size() << endl; // 输出11
    s.to_upper();
    cout << s << endl; // 输出HELLO WORLD
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:30:00