2015-12-15 165 views
0

我開發簡單的C++類來測試C++對象何時銷燬;現在我有一個問題,當一個對象按函數返回時,C++創建一個新對象並返回該對象,並在返回引用時銷燬對象,我的錯誤是什麼?如何在不創建副本的情況下返回對象?

簡單的類如下所示。

#include <iostream> 

using namespace std; 

static int freeCounter=0; 

class TestCopy { 
private: 
    string pStr; 
public: 
    TestCopy(const TestCopy &obj){ 
     pStr=obj.pStr; 
    } 
    TestCopy(string &test){ 
     pStr=test; 
    } 
    ~TestCopy(){ freeCounter++; cout << freeCounter <<"\t" << pStr << endl; } 

    TestCopy get(){ 
     TestCopy x=*this; 
     return TestCopy(x); // -> TestCopy(x) is first destroy in result 
    } 

    string getStr(){ 
     return pStr; 
    } 
}; 

int main(){ 
    string xstr="test"; 
    TestCopy x(xstr); // x is third destroy 
    TestCopy x2=x.get(); // x2 is second destroy 

    cout << x.getStr() << endl; 

    return 0; 
} 

,並導致功能獲取

1 test 
test 
2 test 
3 test 
+0

的問題是,這些都不'TestCopy'are的動態分配的,所以當超出範圍,他們被摧毀。 – Rodolfo

+0

你必須明確地說,你正在函數簽名'TestCopy&get(){'注意到'''我添加了 – Rodolfo

+1

並不完全正確,@Rodolfo。Copy elision會在返回問題時處理複製構造,並且返回本地作爲參考將在MohsenTi的面部爆炸,因爲返回的引用不再存在。 Moe on copy elision:http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization – user4581301

回答

-1

謝謝您的幫助,我發現我的錯誤@seaman。 通過改變

TestCopy x=*this; 

const TestCopy &x=*this; 

問題解決

+0

爲什麼當你說'return * this'時你需要'x'? – juanchopanza

1

x是一個本地對象,當函數結束時,X將被銷燬。

所以,x是所述第一銷燬。

0

首先OP的代碼進行審查。我稍微修改了一下,以便更明顯地發生。

#include <iostream> 

using namespace std; 

static int allocCounter = 0; 

class TestCopy 
{ 
private: 
    string pStr; 
    int counter; 
public: 
    TestCopy(const TestCopy &obj) 
    { 
     allocCounter++; 
     counter = allocCounter; 
     cout << "copy construct " << counter << endl; 
     pStr = obj.pStr; 
    } 
    TestCopy(const string &test) 
    { 
     allocCounter++; 
     counter = allocCounter; 
     cout << "string construct " << counter << endl; 
     pStr = test; 
    } 
    ~TestCopy() 
    { 
     cout << counter << "\t" << pStr << endl; 
    } 

    TestCopy get() 
    { 
     TestCopy x = *this; // copy constructed 
     return TestCopy(x); // copy constructed and copy elision 
    } 

    string getStr() 
    { 
     return pStr; 
    } 
    TestCopy & operator=(const TestCopy &obj) 
    { 
     cout << "assigned " << obj.counter << " to "<< counter << endl; 

     pStr = obj.pStr; 
//  counter = obj.counter; deliberately left out 
     return *this; 
    } 

}; 

int main() 
{ 
    string xstr = "test"; 
    TestCopy x(xstr); // string constructed 
    TestCopy x2 = x.get(); // Would be a copy constructed if not for copy elision 
    return 0; 
} 

輸出

string construct 1 
copy construct 2 
copy construct 3 
2 test 
3 test 
1 test 

注意即使TestCopy x=*this;

好吧賦值操作符的呼叫。現在我們該如何砍掉一些呢?

首先我們得到get

TestCopy get() 
{ 
    return *this; // copy constructed. Or is it? The copy construction could 
        // happen at the caller. Either way it is copied and elided 
} 

輸出

string construct 1 
copy construct 2 
2 test 
1 test 

所以去掉冗餘副本在這一點上,我們知道有沒有必要獲取複製或分配,因爲return語句會爲我們做。這是關於OP的問題的重要部分。

但是,如果我們改變main了一下,添加一個賦值運算符,我們可以看到一個更有趣的行爲。

int main() 
{ 
    string xstr = "test"; 
    TestCopy x(xstr); // string constructed 
    TestCopy x2(""); //string constructed 
    x2 = x.get(); // assigned and a copy construct when returning from get 
    cout << "done main" << endl; 
    return 0; 
} 

輸出

string construct 1 
string construct 2 
copy construct 3 
assigned 3 to 2 
3 test 
done main 
2 test 
1 test 

get返回被分配到x2,然後銷燬。 x2被破壞,最後x

相關問題