2017-07-18 68 views
-2

我想在C++ 11中創建一個「靜態類」,即只有靜態方法並且不可能實例化或繼承的類。 想出了以下解決方案:通過「刪除」複製構造函數來阻止C++ 11類的實例化

class Foo final { 
    public: 
    static void methodA(...); 
    static int methodB(...); 
    Foo(const Foo&) = delete; 
}; 

這樣編譯器創建既不是默認的也不是拷貝構造函數。 Visual Studio的IntelliSense也證實了這一點,因爲它在輸入Foo(時不提供任何構造函數自動完成。

我想知道這個解決方案是否以任何方式比使默認構造函數私有的「常見」方法更可取。有沒有優點/缺點?

+12

爲什麼不使用名稱空間呢? – jamesdlin

+0

是的,如果你沒有使用過類功能,那麼你不會創建一個類。你正在創建一個名字空間。 – tadman

+0

使構造函數保持私有狀態是我們所能做的,沒有delete關鍵字。效果是相同的,並且不生成代碼。如果僅僅因爲它更具可讀性,我會使用新的語法。 –

回答

3

以使男星私人所不同的是,這是用於舊版C++標準,不允許您使用= delete。這樣做的舊形式並不像「乾淨」,因爲它依賴鏈接器提供錯誤消息,而不是編譯器。如果你的ctor是私有的,並且沒有定義,但是無論如何你都要調用它(例如,從一個類函數中),鏈接器將負責中止構建過程併產生一個錯誤(因爲ctor只是聲明的,沒有定義。 )由於編譯器現在可以直接發出錯誤,因此= delete表單更清潔。

但是,您在此之後的內容與命名空間非常相似。所以我建議你這樣做,而不是:

namespace Foo { 
    void methodA(...); 
    int methodB(...); 
} 

這不會更改調用函數的完全限定的形式。像以前一樣,您可以撥打methodA()Foo::methodA(),因此這應該作爲一個直接替代品。

如果需要,您還可以使用using聲明刪除Foo::。例如:

using Foo::methodA; 
methodA(); // Valid call. 

或者只是using Foo;,使從Foo所有標識符到當前範圍,而無需任何前綴他們與Foo::。 (常用的警告在這裏適用於名稱空間污染。)

您不能使用靜態類功能執行此操作。

1

看起來像您使用的是錯誤的工作工具,namespace(按@ jamesdlin的評論)會做你想要什麼:

namespace Foo { 
    void methodA(...); 
    int methodB(...); 
};