如何才能找出什麼時候正在創建和銷燬臨時對象以及如何進行?如何知道何時創建和銷燬臨時對象?
舉個例子,假設我們有一個名爲Foo
類和函數返回一個Foo
對象,它的參數是一個對象,一個對象的引用。
Foo func(Foo a ,Foo & b);
有多少對象與我一起創建瞭解它?
它是使用複製構造函數還是常規創建的?
如何才能找出什麼時候正在創建和銷燬臨時對象以及如何進行?如何知道何時創建和銷燬臨時對象?
舉個例子,假設我們有一個名爲Foo
類和函數返回一個Foo
對象,它的參數是一個對象,一個對象的引用。
Foo func(Foo a ,Foo & b);
有多少對象與我一起創建瞭解它?
它是使用複製構造函數還是常規創建的?
使用構造函數和析構函數,在它們中插入一條print語句。
#include <iostream>
class Foo
{
public:
Foo(){}
Foo(const Foo &other) {std::cout<<"A copy was made\n";}
Foo(Foo &&other) {std::cout<<"Foo was moved\n";}
~Foo(){std::cout<<"Destroyed Foo\n";}
};
Foo func(Foo a, Foo &b)
{
return a;
}
Foo func_const(const Foo &a, Foo &b)
{
return a;
}
Foo func_temp()
{
return Foo();
}
int main()
{
Foo f;
func(f, f);
std::cout<<"\n\n\n";
func_const(f, f);
std::cout<<"\n\n\n";
Foo g = func_temp();
}
上述打印(使用ideone):
Foo constructed
A copy was made
Foo was moved
Destroyed Foo
Destroyed Foo
A copy was made
Destroyed Foo
Destroyed Foo
Destroyed Foo
隨着函數簽名:
Foo func(Foo a, Foo &b)
,參數a
可進行復印。複製也可能被編譯器的優化所忽略。參數b
從不復制,因爲它是按引用傳遞的,並且通常表示您將修改傳遞的對象;不修改副本。
當返回一個Foo時,它可能會也可能不會返回一個副本。這取決於你班級的定義。請參閱http://en.wikipedia.org/wiki/Return_value_optimization
將print語句添加到另一個空的構造函數可能會影響何時以及在何種情況下調用構造函數(以及何時以及在什麼情況下創建對象):http://stackoverflow.com/a/8287110/777186 – jogojapan
@ jogojapan即使構造函數有副作用,編譯器也可以繞過對象的創建來執行優化。 – bolov
@bolov,但只要遵循as-if規則,編譯器也可以在copy copy不允許的情況下刪除副本。添加打印語句會改變它。 – juanchopanza
您是在談論內存分配時使用'new'還是實例化類?你總是可以做一個自定義的'auto_ptr'類。 – zero298