2013-04-23 201 views
1

我有我的測試類來做我自己的字符串函數。我有一個複製析構函數的問題。複製構造函數調用析構函數C++

我有2個字符串:s1和s2。我調用函數s3 = s1 + s2;

它首先調用operator +函數,當它結束時調用析構函數。正因爲如此,operator =函數中的字符串對象是空的。我怎樣才能解決這個問題?

析構函數:

String::~String() { 
    if (this->str) 
    delete[] str; 
    str = NULL; 
    len = 0; 
} 

拷貝構造函數:

String::String(const String& string) { 
    this->len = string.len; 
    if(string.str) { 
    this->str = new char[string.len+1]; 
    strcpy(this->str,string.str); 
    } else { 
    this->str = 0; 
    } 
} 

operator=

String & String::operator= (const String& string) { 
    if(this == & string) 
    return *this; 

    delete [] str; 

    this->len = string.len; 

    if(string.str) { 
    this->str = new char[this->len]; 
    strcpy(this->str,string.str); 
    } else { 
    this->str = 0;  
    } 

    return *this; 
} 

operator+

String& operator+(const String& string1 ,const String& string2) 
{ 
    String s; 

    s.len = string1.len + string2.len; 
    s.str = new char[string1.len + string2.len+1]; 
    strcpy(s.str,string1.str); 
    strcat(s.str,string2.str); 

    return s; 
} 

回答

7

operator+不應通過引用返回局部變量。

將退貨類型operator+更改爲String。即,使簽名:

String operator+(String const& lhs, String const& rhs) 

你可能也需要寫一個「移動的構造」爲您String類:String(String&& other),如果你正在寫在C++ 11的代碼。

一個簡單的移動構造函數:

String::String(String&& other): len(other.len), str(other.str) { 
    other.len = 0; 
    other.str = nullptr; 
} 

這不是必須的,因爲在return語句複製你的operator+下不平凡的優化級別可能會被「省略的」你的編譯器,但仍良好的做法。

+0

由於它的工作的=副本:d我被困在這了一點。 – marktielbeek 2013-04-23 19:17:44

3

它調用析構函數,因爲String s將超出您的運算符+超載範圍。您的operator + overload需要返回一個副本而不是參考。

因此,你應該你的運營商+改爲

String operator+(const String& string1, const String& string2) 
0

是啊,我得到了你的問題

的事情是,當你從+運算符函數返回一個臨時對象的引用,然後你要分配此到主體中的其他對象所以在這裏=重載函數被調用到你正在傳遞一個對象的引用不再存在

因此,無論你是否可以從+運算符函數返回一個副本

你可以通過在overlaoded功能