对象传参、返回与接收的优化
C++的编译器会给一个空的类提供六个函数
- 默认构造函数
- 析构函数
- 拷贝构造
- 拷贝赋值
- 移动构造
- 移动赋值
在提供构造函数时,编译器将不再提供默认构造。
这些函数在对象传参、返回对象、接收对象时会自动调用,所以有必要进行相应的优化,减少这种隐式调用。
以下面这段代码为例:
#include <iostream> class Foo { public: Foo(int a) : _a(a) { std::cout << "Foo(int)" << std::endl; } ~Foo() { std::cout << "~Foo()" << std::endl; } Foo(const Foo &val) : _a(val._a) { std::cout << "Foo(const Foo&)" << std::endl; } Foo(Foo &&val) : _a(val._a) { std::cout << "Foo(Foo&&)" << std::endl; } Foo &operator=(const Foo &val) { if (this == &val) return *this; _a = val._a; return *this; } Foo &operator=(Foo &&val) { if (this == &val) return *this; _a = val._a; return *this; } int getA() const { return _a; } private: int _a; }; Foo bar(Foo f) { // 3. Foo(const Foo&) int a = f.getA(); Foo tmp(a); return tmp; } Foo bar2(const Foo &f) { return Foo{f.getA()}; } int main() { { // 优化前 Foo f1(42); // 1. Foo(int) Foo f2(10); // 2. Foo(int) f2 = bar(f1); // 4. Foo(int) } std::cout << "============================" << std::endl; { // 优化后 Foo f3(42); // 1. Foo(int) Foo f4 = bar2(f3); // 2. Foo(int) } }
运行结果如下:
eric@eric-XPS-13-9360:~/tmp$ g++ main.cpp eric@eric-XPS-13-9360:~/tmp$ ./a.out Foo(int) Foo(int) Foo(const Foo&) Foo(int) ~Foo() ~Foo() ~Foo() ~Foo() ============================ Foo(int) Foo(int) ~Foo() ~Foo()
不同编译器可能执行结果不同,对编译优化的设置也会影响运行结果。
优化效果还是很明显的,优化前有四次构造,对应四次析构,而优化后仅发生两次构造和析构。
主要理解以下三个优化规律:
- 对象传参,使用
&
传递,在必要时加const
修饰 - 对象返回,获取成员后,通过构造函数直接返回临时对象
- 对象接收,直接构造而不是通过赋值
在利用临时对象构造新对象时,编译器会自动优化,将临时对象的构造、新对象的拷贝构造优化为一次构造。
尽可能使用临时对象的直接构造,而不产生中间对象。
本文来自博客园,作者:EricLing0529,转载请注明原文链接:https://www.cnblogs.com/ericling0529/p/18148749
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?