2014-01-18 103 views
1

如何才能找出什麼時候正在創建和銷燬臨時對象以及如何進行?如何知道何時創建和銷燬臨時對象?

舉個例子,假設我們有一個名爲Foo 類和函數返回一個Foo對象,它的參數是一個對象,一個對象的引用。

Foo func(Foo a ,Foo & b); 

有多少對象與我一起創建瞭解它?
它是使用複製構造函數還是常規創建的?

+0

您是在談論內存分配時使用'new'還是實例化類?你總是可以做一個自定義的'auto_ptr'類。 – zero298

回答

3

使用構造函數和析構函數,在它們中插入一條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

+2

將print語句添加到另一個空的構造函數可能會影響何時以及在何種情況下調用構造函數(以及何時以及在什麼情況下創建對象):http://stackoverflow.com/a/8287110/777186 – jogojapan

+1

@ jogojapan即使構造函數有副作用,編譯器也可以繞過對象的創建來執行優化。 – bolov

+2

@bolov,但只要遵循as-if規則,編譯器也可以在copy copy不允許的情況下刪除副本。添加打印語句會改變它。 – juanchopanza