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

使用sstream导致自定义异常类拷贝构造函数被隐式删除报错问题

问题根因

报错核心原因是:std::stringstream 类型不支持拷贝构造,你把它定义为tornadoException类的成员变量后,C编译器会自动删除该类的默认拷贝构造函数。而C抛出异常的底层逻辑要求异常对象必须支持拷贝构造,因此触发编译报错。

你的代码中ss成员仅在带参构造函数里用来拼接字符串,转成message存储后就没有其他用途,完全没必要作为类成员存在,属于冗余设计导致的问题。

解决方案(最优,改动最小)

直接删除类的stringstream成员变量,拼接逻辑改为在构造函数内定义局部stringstream即可:

1. 修改 tornadoException.h

删除私有块里的stringstream ss;行,同时建议移除头文件的using namespace std;避免全局命名空间污染:

#ifndef tornadoException_h
#define tornadoException_h

#include <string>

class tornadoException{
public:
  tornadoException();
  tornadoException(int m);
  std::string what();
private:
  std::string message;
};

#endif

2. 修改 tornadoException.cpp 带参构造函数

把原来用成员ss的逻辑改为局部变量:

tornadoException::tornadoException(int m){
  std::stringstream ss; // 局部变量,用完自动销毁,不会影响类的拷贝构造
  ss << "Tornado: " << m << " miles away! and approaching!";
  message = ss.str();
}

可选优化

catch异常时建议用常量引用接收,避免不必要的对象拷贝,也能兼容更多特殊的异常类设计:

catch(const tornadoException& tornadoObj){
  cout << tornadoObj.what();
}

其他可选方案(仅作原理说明,不推荐)

如果你确实需要把stringstream作为类成员保留,可以把成员改为std::unique_ptr<std::stringstream>智能指针,手动实现类的拷贝构造函数,将旧对象ss.str()的内容写入新对象的stringstream即可,但该方案会增加不必要的性能开销和代码复杂度,异常类场景下完全不需要。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:48:02