2011-07-27 141 views
3

標題基本上說這一切。我主要想這樣做,以便我可以創建一個可以初始化其他API中的其他函數的參數的對象(比如自定義字符串對象)。下面是我試圖讓一個自定義的整數類工作的一個例子:如何創建可以初始化C++數據類型的類?

#include <iostream> 
using namespace std; 

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 

    friend int &operator=(int &i, test t); 
}; 

int &operator=(int &i, test t) 
{ 
    return (i = t.member); 
} 

int main() 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 

不幸的是,我收到一個錯誤,指出運營商=需要一個成員函數。我理解C++標準的目標是防止賦值運算符的靜態和非成員重載被實現,但是有沒有其他方法可以實現這一點?感謝您的任何幫助/建議!

回答

3

你正在嘗試做需要一個轉換操作符

operator int() 
{ 
    return this->member; 
} 

要嘗試寫(只含整數成員)類,你需要重載=運營商。

=運算符是編譯器爲每個類默認生成的成員函數之一。警惕是,它會對類成員進行簡單的一點一點的複製(淺拷貝),因爲你只有整數,對你來說應該足夠好。

您將需要重載=運營商,如果你有動態分配指針作爲成員函數,因爲在這種情況下,這些指針的淺拷貝會導致含成員指針指向同一個動態內存位置&的所有對象如果其中一個對象完成它的生命週期,則其他對象將留下一個懸掛指針。
作爲@Tony,正確地點出評論淺拷貝是通常不好,但並不總是。請參閱他對於場景的評論。

如果完全想讓分配操作員超載,請檢查Copy and Swap Idiom以正確的方式執行操作。

您還應該看看Rule of Three

+1

「[運算符=]確實通過操作數位副本(淺拷貝)一個簡單的位」 ...的操作數是一個陌生的名詞使用......也許成員變量?它爲具有它們的成員調用複製構造函數 - 它們可能不會執行逐點淺拷貝(例如'std :: string')。 Re指針的淺拷貝是危險的:這通常是正確的,但並不總是 - 例如(通常是'const')指向靜態引用數據的指針可以被安全地複製。 –

+1

@Tony:謝謝!我將這一點關於操作數改爲成員。承認,那不是太冗長。我指的是帶有動態內存分配的成員指針最常見的情況,因爲這是超載的默認分配對新手最大的傷害。雖然,你的評論應該有助於破譯閱讀答案的例外,所以謝謝:) –

+1

是的 - 我可以按照你的想法,只是擔心「新手」可能會認爲「任何指針=需要你自己的操作員=」指導方針是更多的規則。這是一個很好的指導方針,正如你所說的幫助新手。動態記憶的另一個危險信號,儘管不是100%相關:例如被指向的對象可能被'main()'中調用的工廠方法返回,並且只在應用程序退出前不久被刪除,而指向它的對象的生命期被「包含」在其中)。乾杯。 –

5

這不是使用賦值操作符完成的,而是使用重載的類型轉換。這將使您的主要功能按預期工作:

#include <iostream> 
using namespace std; 

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 
    operator int() const {return member;} 
}; 

int main() 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
} 
+2

+1,儘管'operator int()'應該是'const',並且'test(int)'更安全(儘管有時不太方便 - test t = 90)。 –

+0

@Tony:謝謝你的提示。 – manol

+0

這似乎起作用!謝謝! – AutoBotAM

1

賦值運算符不能是朋友函數。賦值運算符只能被聲明爲非靜態成員函數。這是爲了確保它將L值作爲其第一個操作數。 [],()和 - >運算符也是如此。在你的情況下,因爲int是一個內建類型,所以你不能使用成員函數。您可以實現運算符int()來將您的用戶定義類型轉換爲int。

+0

你不能在'int'中定義非靜態成員函數,你能嗎? – unkulunkulu

+0

@unkulunkulu,因爲int是一個內建類型。答案已更新。 –

3

試試這個:

class test 
{ 
public: 
    int member; 
    test(int i) : member(i) {} 

    operator int() {return this->member;} 
}; 

int main(void) 
{ 
    int i; 
    test t = 90; 

    cout << (i = t); 
    return 0; 
}