c++的命名返回值优化问题

背景知识

copy构造函数在以下三种情况下会调用:

  • 对象初始化
  • 函数形参值传递
  • 返回局部对象

问题引出

看c++运算符重载时碰到一个问题,代码如下,文件名为operatorTest.cpp,重点看看operqtor+这个函数。

# include <iostream>
using namespace std;

class demo
{
private:
	int a;
	int b;
public:
	demo(int a = 0, int b = 0)
	{
		cout << "constructor..." << endl;
		this->a = a;
		this->b = b;
	}
	demo (const demo & d)
	{
		cout << "copy constructor..." << endl;
		this->a = d.a;
		this->b = d.b;
	}
	demo operator + (demo & another)
	{
		demo d(this->a + another.a, this->b + another.b);
		return d;
	}
	void print()
	{
		cout << "a : " << a << "b : " << b << endl;
	}
};

int main (void)
{
	demo a(1,2), b(3,4);
	demo c;
	c = a + b;
	c.print();
	return 0;
}

可以看到 operator+ 这个函数返回了一个局部对象,根据copy构造函数的调用时机可知,copy构造函数这时候应该会调用,我在终端输入

feilei /Users/feilei/repos/workspace/cpp $ g++ operatorTest.cpp -o operatorTest
feilei /Users/feilei/repos/workspace/cpp $ ./operatorTest

编译执行operatorTest.cpp时结果如下

constructor...
constructor...
constructor...
constructor...
a : 4b : 6

可以看出,并未调用copy构造函数。问题就是这样,根据copy函数的调用规则,应该有copy构造函数调用,但是实际上并没有。

问题解决

一番搜索之后,发现这个问题早已经有人提出并且得到了解决方案。答案是:gcc编译器做了优化,因为那一次copy函数调用并不是必要的。gcc和g++千丝万缕的联系可以参见这个:gcc和g++是什么关系?

如何要忽略编译器做的优化,可以采用如下命令:

feilei /Users/feilei/repos/workspace/cpp $ g++ -fno-elide-constructors operatorTest.cpp -o operatorTest
feilei /Users/feilei/repos/workspace/cpp $ ./operatorTest

编译结果如下:

constructor...
constructor...
constructor...
constructor...
copy constructor...
a : 4b : 6

reference

C++函数返回局部变量对象的优化-不调用复制构造函数
命名返回值优化
急急急! 求大神啊。 函数返回值是对象,是调用了拷贝构造函数?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章