背景知識
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++函數返回局部變量對象的優化-不調用複製構造函數
命名返回值優化
急急急! 求大神啊。 函數返回值是對象,是調用了拷貝構造函數?