簡體   English   中英

C ++私有靜態成員變量與自由非成員的比較

[英]c++ private static member variables compared to free nonmember


我是C ++的新手,對私有靜態成員或“免費非成員”有疑問。

我可以這樣寫我的代碼:

// MyClass.h - Version 1
class MyClass
{
public:
    MyClass();
    ~MyClass();
private:
    static int iValue;
};

// MyClass.cpp
int MyClass::iValue = 123;

另一種沒有私有成員的方式,在cpp內部進行內部鏈接

// Version 2 - static 
static int iValue = 123;

// or anonymouse namespace
namespace
{
    int iValue2 = 123;
}

我可以看到的唯一區別是,即使我無法使用它,也可以從班級外部獲得“可見性”。
如果要在外部或派生類中使用iValue,我將在版本1中將靜態成員聲明為public或受保護的類,或者在該類之上被完全全局聲明。 關鍵字const對我來說還不清楚。

class MyClass
{
private:
    static const int iValue;
// (...)
}

我總是希望盡可能多地從外面隱藏東西。

簡而言之:我為什么有理由偏愛版本1而不是版本2?

親切的問候
尼西

封裝是面向對象編程的主要范例之一,因此,如果您的靜態成員僅由類本身使用(例如,計算類對象的數量),則應使用版本1(私有靜態成員)。 當然,如果您希望派生類能夠使用它,則應該將其設置為protected

如果該變量未特別綁定到任何類,則應使用版本2/3(靜態全局變量),並且可以在不同的地方使用該版本。 但是,有人可能會認為需要全局變量的代碼設計不當,而使用全局變量被認為是一種不好的風格。

如果您需要特定於特定類的恆定值(例如,汽車的車輪數),則可以使用私有靜態const成員。

MyClass(類而不是實例)是否具有iValue

是=>使其成為靜態成員。

否=>做其他事情。

您想知道該怎么做,這表明您現在沒有明顯的權衡取舍。 這是一個很好的指示,您可以並且應該做正確的事©,這可以使其他人盡可能簡單地理解您的代碼,這又意味着:着重於代碼的語義。

做正確的事情的人的另一點是:關注點分離,您的班級應該只做一件事情,一件事情。 如果iValue在班級中沒有任何關系,但您可能希望將它放在某個班級中的某個地方:請勿隨意進行。

這個領域的設計決策需要權衡一些事情,這很容易理解,因此每次需要這種選擇時,您都可以權衡利弊:

  • 匿名名稱空間或靜態非成員允許翻譯單元中的所有更高版本代碼完全訪問。

    • 用於實現文件(例如“ .cc” /“。cpp”)中,它們使您擁有一些靜態數據/功能-在對象的符號表中不是extern的-無法通過其他轉換單元的代碼進行訪問。

      • 較小的符號表有時可以減少程序鏈接和/或加載時間。

      • 通常認為這比私有成員變量具有更少的封裝 ,因為一個以上類的代碼和朋友可以訪問/更改數據(但是類成員的定義可能分布在許多翻譯單元中,並且私有數據更容易受到攻擊。某些類型的“黑客入侵”訪問,例如客戶端提供的模板專業化-從未如此簡單。

        • 如果希望翻譯單元中的更多代碼可以訪問,則較少的封裝是可取的:您正在尋找一種“適合”實際需求的方法。
      • 這減少了(重新)編譯依賴性(在Lakosian術語中也稱為“物理依賴性”),這意味着您可以在不編輯標題的情況下更改數據/功能,並且僅翻譯單元的重新編譯就可以鏈接新的數據/行為以進行合並。但是,有許多客戶端對象/可執行文件; 與此相反,對頭文件的編輯往往需要重新編譯重新鏈接所有要合並的客戶端代碼。 在企業級開發中,這對於低級庫的更改可能是一個大問題。

    • 在標頭中很少使用它們,因為每個包含這樣標頭的翻譯單元都會獲得數據/函數的獨立“副本”,而且程序很少需要每個翻譯單元存儲狀態的情況非常少; 通常無法清晰地映射到程序數據中具有邏輯意義的分區(例如,運行時每個線程,每個“用戶”),並且即使可以對程序進行結構化以使其看起來很有用,通常最好使用以下方法管理多個數據副本:對象實例,使其與翻譯單元分離,從而為以后的源代碼重構/重構保留靈活性。

    • 他們無法訪問任何類的私有/受保護成員,並且建議他們可能與任何特定的類無關,並且可能可重用,這取決於真實性如何,可以幫助或挫敗開發人員在分析數據使用情況時的理解或功能行為/實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM