2011-08-31 73 views
5

在「C++程序設計語言」預定義的含義,在265頁中,作者提出了以下聲明:問題對運營商

由於歷史的偶然的,運營商=(轉讓),&(地址 - ),和(排序; 第6.2.2節)在應用於類對象時具有預定義的含義。這些預定義的意義可以 通過使他們的私人而不能接觸到一般用戶:

那麼下面的例子說明:

class X { 
private: 
void operator=(const X&); 
void operator&(); 
void operator,(const X&); 
// ... 
}; 

void f(X a, X b) 
{ 
    a = b; // error: operator= private 
    &a;  // error: operator& private 
    a,b; // error: operator, private 
} 

我不是很瞭解做這些「錯誤」意見指至?這是否意味着我不應該這樣定義一個函數f,或者所有的=&,並且,運營商應按照默認方式來使用,沒有必要重新定義它們呢?

回答

8

這個例子簡單顯示了一種方法,以防止自己或由使用運算符,它可以在不具有類定義中使用的代碼的其他開發人員,因爲它們會自動產生(並且具有用於操作默認含義它們代表)。

意味着,如果你嘗試分配ba(符合a = b),它會導致一個錯誤,因爲賦值運算符是在類定義私有的例子的作者。在地址中的第二行中,並且在第三逗號操作符的情況下發生

類似的錯誤。

如果你知道它們不應該被使用(或尚未實現),那麼使默認的操作符/構造函數是私有的是好的,因爲可能會意外地使用非常頻繁的操作符,如賦值或複製構造函數,不知道它的默認行爲與類生命週期衝突。如果這樣的操作符或構造函數在類設計的最初階段被設置爲私有的,編譯器將生成編譯時錯誤,而不是在程序員意外地使用該方法的情況下執行潛在危險的操作,恕不另行通知。

認爲默認的賦值操作符和成員指針:它會複製指針,而你可能希望對象是數據的所有者。然後,在某人將一個對象分配給另一個對象而不知道該分配未實現之後,最終會出現雙重空閒錯誤。相反,如果操作員是私人的,你會得到一個很好的錯誤,代碼甚至不會編譯,你會知道發生了什麼。

1

提供您自己的任何操作符實現與實現類方法基本相同。操作員和方法在可訪問性方面相同。你所做的是禁止從調用者的代碼訪問操作員。

,如果你定義的私有方法,然後試圖從一些代碼,是不是你的類的一部分調用它這絕對是一樣的。只要讓操作員公開,錯誤就會消失。

1

它基本上防止從製造「X」對象並使用「=」,「&」,和「」操作員在該類的任何一個。因爲這個類的作者可能實現這些對象的含義與該類的消費者可能認爲它們的含義完全不同......所以最好在含糊不清的情況下儘量防止它們被使用。

1

函數f是用戶嘗試使用私有操作符的示例。它通過使它們變爲私密來向你顯示你正在阻止的代碼。註釋// error意味着包含該行的程序將因指定的原因而無法編譯。

5

作者打算在這裏指出,運營商=,&,通常隱含可用於類。
所以,如果你不希望你的物體通過它們進行操作,那麼你聲明它們爲private,從而不允許它們的使用。

由於它們被聲明爲private,所以你不能在類之外訪問它們,並且編譯器會給你一個編譯錯誤。該功能就是一個例子。

+0

我發現這個答案比最上面的一個更清晰:*預定義的含義*的意義在於它們存在並且將在默認情況下工作,並且*禁止*在C++ 03中的行爲的唯一方法是通過聲明它們爲'private'(C++ 0x添加'delete'關鍵字) –

0

在討論錯誤之前,這裏的一個關鍵是要明白這些操作會隱式提供給您的班級。這是Scott Meyers的建議「知道C++默默地編寫和調用什麼函數」的精髓。

C++將自動爲您的類實現賦值運算符,但可能無法正確執行(例如,如果您的類包含指針成員變量)。通過明確定義賦值運算符,您告訴編譯器使用您的實現,而不是爲您生成一個。並且通過將它私有化,你基本上不允許將一個類實例分配給另一個類實例。任何你試圖在你的代碼中執行此操作的地方,編譯器都會抱怨,如果你不想分配,這是一件好事。

在函數f中,作者向您展示了這些語句不會編譯,因爲操作符是如何在類中定義的。爲你的類重新定義運算符是完全可以接受的,有時它也是必須的(例如,在你的類中實現一個指針成員變量的深層副本)。這個例子的要點是要證明:a)你可以爲你的類提供你自己的這些運算符的實現,以及b)因此你可以控制運算符是否被正確支持和實現。