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

C++中Abc类构造器选型:A+B还是C?现代C++优化是否可信?

关于Abc类构造器的选择问题

核心结论

结合你的场景(Def类拷贝成本极高、移动成本低,且构造Abc后仍需保留原Def对象),最优方案是同时提供B(const引用拷贝构造器)+ A(移动构造器);如果想简化代码,也可以只提供C(值传递构造器),现代C++的优化能避免冗余拷贝,但要注意场景限制。

逐个问题拆解

1. 早年值传递(C选项)的两次拷贝问题

早年C++(C++11之前)没有移动语义,值传递构造器确实会导致两次拷贝:

  • 第一步:调用Abc构造器时,实参Def对象会被拷贝到形参;
  • 第二步:形参再被拷贝到Abc的成员变量里。
    两次大内存拷贝的开销完全无法接受。

2. 现代C++对值传递的优化是否属实?

属实。C++11引入移动语义后,编译器会根据实参的类型自动选择拷贝或移动:

  • 如果实参是左值(比如你场景中需要保留的原Def对象),编译器会将值传递的过程优化为「一次拷贝」(甚至可能直接省略拷贝,即NRVO优化);
  • 如果实参是右值(比如临时Def对象、或者用std::move()显式转换的对象),编译器会触发移动操作,把形参的资源直接转移到Abc的成员,完全避免拷贝。

3. 仅保留C构造器的情况

如果只提供值传递构造器Abc(Def d):

  • 编译器不会自动改成引用传递,它还是会按值传递的逻辑处理,但会通过移动语义或NRVO优化来减少拷贝;
  • 但在你的场景中,因为构造Abc后还要用原Def对象,所以你只能传入左值,这时候编译器会做一次拷贝(或者NRVO省略拷贝),开销还是存在。而如果同时提供B和A:
    • 传入左值时,会调用Abc(const Def& d),直接拷贝一次(或者可能被优化);
    • 传入右值时,调用Abc(Def&& d),直接移动,开销极低。

针对你的场景的建议

因为Def拷贝成本极高,且你需要保留原对象,所以:

  • 必须提供B(const引用拷贝构造器),确保传入左值时只做一次必要的拷贝;
  • 同时提供A(移动构造器),方便在需要传入临时对象或可转移的Def对象时,用移动代替拷贝,节省开销;
  • 如果你想简化代码,只写值传递构造器也能工作,但不如同时提供A+B灵活,且某些情况下可能无法触发最优的优化。

内容的提问来源于stack exchange,提问作者no one special

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:33:17