对象传参、返回与接收的优化

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修饰
  • 对象返回,获取成员后,通过构造函数直接返回临时对象
  • 对象接收,直接构造而不是通过赋值

在利用临时对象构造新对象时,编译器会自动优化,将临时对象的构造、新对象的拷贝构造优化为一次构造。
尽可能使用临时对象的直接构造,而不产生中间对象。

posted @   EricLing0529  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
点击右上角即可分享
微信分享提示