我正在玩C++來提醒自己。所以我嘗試了運算符+重載返回引用。此動機是爲了避免不必要的對象複製。看看這個例子。我使用+創建了類String和串聯的字符串。這只是實驗,所以你會注意到一些醜陋的東西作爲公共屬性。從臨時對象重載operatora和表達式返回引用
這裏是代碼的相關部分。
String.hpp
#ifndef STRING_HPP_
#define STRING_HPP_
#include <iostream>
using namespace std;
#ifndef CPP11
typedef wchar_t unicode16;
#else
typedef char16_t unicode16;
#endif //CPP11
class String {
unicode16 * value;
unsigned strLength;
void initEmpty() {
value = 0L;
strLength = 0;
}
static unsigned counter;
public:
static String ** trash;
unsigned id;
String::String() : value(0L), strLength(0){
id=counter++;
trash[id]=this;
cout << "Creating empty: " << id << "\n";
}
String::String(const String &str);
String(const char *);
String(const unicode16 *);
unsigned length() const {
return strLength;
}
~String() {
wcout << L"Deleting " << id << ": " << value << L"\n";
trash[id]=0L;
delete value;
}
String & operator +(String &);
unicode16 * getValue() {
return value;
}
};
#endif /* STRING_HPP_ */
String.cpp
#include "String.hpp"
#include "../exception/IllegalArgumentException.h"
#include <string.h>
unsigned String::counter = 0;
String ** String::trash = new String *[100]();
String::String(const String & str) {
value = new unicode16[str.strLength + 1];
strLength = str.strLength;
for(int i = 0; i < strLength ; i++) {
value[i] = str.value[i];
}
value[strLength] = 0;
id = counter++;trash[id]=this;
wcout << L"Created (copy): " << id << ": " << value << L"\n";
}
String::String(const char *charArray) {
if (charArray == 0L) {
throw IllegalArgumentException("Char array pointer is null");
}
strLength = strlen(charArray);
value = new unicode16[strLength + 1];
for (int i = 0; i < strLength; i++) {
value[i] = (unicode16)charArray[i];
}
value[strLength] = 0;
id = counter++;trash[id]=this;
wcout << L"Created (char *): " << id << ": " << value << L"\n";
}
String::String(const unicode16 *utfArray) {
if (utfArray == 0L) {
throw IllegalArgumentException("Unicode array pointer is null");
}
strLength = wcslen(utfArray);
value = new unicode16[strLength + 1];
for (int i = 0; i < strLength; i++) {
value[i] = utfArray[i];
}
value[strLength] = 0;
id = counter++;
trash[id]=this;
wcout << L"Created (unicode): " << id << ": " << value << L"\n";
}
String & String::operator +(String &str) {
unsigned newLength = length() + str.length();
unicode16 * newArray = new unicode16[newLength + 1];
wcscpy(newArray, value);
wcscpy(newArray + strLength, str.value);
String * strPointer = new String();
strPointer->value = newArray;
strPointer->strLength = newLength;
String &result = *strPointer;
wcout << L"Empty loaded: " << result.id << ": " << result.value << L"\n";
return result;
}
和主方法
#include "../string/string.hpp"
#include <iostream>
using namespace std;
int metodica(void) {
String & please = String("Please");
String meString = "me";
String & me = meString;
String & delStrRef = String(" delete ");
String & result1 = please + delStrRef + me;
wcout << result1.getValue() << L"\n";
delete &result1;
return 0;
}
int main(void) {
metodica();
cout << "These are not deleted\n";
for (int i = 0; i < 100; i++) {
if (String::trash[i] != 0L) {
wcout << String::trash[i]->getValue() << "\n";
}
}
}
使用VS2010編譯器和鏈接在CDT執行此我得到以下輸出
創建(字符*):0:請
創建(字符*):1:我
創建(字符*):2:刪除
創建空:3
空裝:3:請刪除
創建空:4
空裝:4:請刪除我
請刪除我
刪除4:請刪除我
刪除2:刪除
刪除1:我
刪除0:請
這些不會被刪除
請刪除
問題是爲什麼臨時對象在表達式中創建請+ delStrRef +我;不會被刪除。它不應該在表達式的末尾被刪除,或者如果引用是臨時對象而不是對象本身,則會變得不同。
閱讀[此](http://en.wikipedia.org/wiki/Copy_elision)和[此] (http://stackoverflow.com/questions/3106110/what-is-move-semantics),然後停止寫難看的代碼。你沒有保存任何東西。 –
它故意醜陋,因爲我想快速看到實際上用臨時對象做了什麼。這當然不是生產或任何嚴重的事情。 – ognjenmi
但無論如何感謝文章。 – ognjenmi