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

抛出引用类型的异常为何会调用拷贝构造函数?

抛出引用类型的异常为何会调用拷贝构造函数?

这其实是C++异常机制的一个核心规则——当你抛出一个对象(哪怕是以引用的形式抛出)时,编译器会自动创建该对象的副本作为异常对象,这个副本会被存储在专门的异常内存区域,用于后续的catch块捕获。而创建这个副本的过程,就必须调用类的拷贝构造函数。

看你给出的这段代码:

struct Error { 
    Error() {} 
    Error(const Error&) = delete; 
}; 

int main() { 
    Error& error = *new Error; 
    throw error; 
}

这里你明确删除了Error的拷贝构造函数,编译器在尝试创建异常对象副本时找不到可用的拷贝构造,自然就会报错:

error: declared here Error(const Error&) = delete;

而当你抛出指针类型时,情况就完全不同了:你实际抛出的是指针变量本身的值(也就是它指向的内存地址),这个值是一个简单的整数类型(在64位系统里就是8字节的数值),复制它不需要调用任何自定义的构造函数——既不需要拷贝指针指向的Error对象,也不需要Error类提供任何特殊成员函数。

比如这段代码:

int main() { 
    Error* error = new Error; 
    throw error; 
}

它能正常编译,因为本质上只是复制了一个内存地址数值,和Error类的拷贝构造函数没有任何关系。

补充个小细节:如果你的类提供了移动构造函数,编译器可能会优先调用移动构造来创建异常对象,但如果移动构造也不可用,就会 fallback 到拷贝构造——但不管是移动还是拷贝,都需要类提供对应的构造函数,否则就会像你第一个例子那样编译失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:04:40