2016-04-03 57 views
-2

我需要從調用class T的常規構造如下禁止用戶:使用新的()在C++作爲構造

T obj (a, b, c); // Compile-time error 
T* objPtr = new T (a, b, c); // OK 

是否有可能在C++?

+4

爲什麼你需要這個?另外,請考慮返回'unique_ptr '以減少資源泄漏的範圍並提高異常安全性。 – juanchopanza

+5

您可以將對象創建封裝到靜態方法或工廠類中。 – soon

+1

這兩種方式都調用相同的構造函數,所以無論你做什麼,都不會執行它。 – Joe

回答

2

您可以通過使用模仿行爲還挺一個factory pattern:用於實例化對象的實例的friend class

class T; 

class TMaker 
{ 
public: 
    static std::unique_ptr<T> MakeT(int a, int b, int c); 
}; 

class T 
{ 
public: 
    void PrintMe() { std::cout << a << ", " << b << ", " << c << std::endl; } 
private: 
    T(int a_, int b_, int c_) : a(a_), b(b_), c(c_) {} 
    int a, b, c; 
    friend class TMaker; 
}; 

std::unique_ptr<T> TMaker::MakeT(int a, int b, int c) 
{ 
    return std::unique_ptr<T>{new T{a, b, c}}; 
} 

現在,用戶可以不再建立直接類:

T v { 1, 2, 3 }; // doesn't work 
T* v = new T{1, 2, 3}; // also doesn't work 

而是他們只能使用以下內容:

std::unique_ptr<T> t = TMaker::MakeT(1, 2, 3); 

但是,請注意,您可能只需要一個XY problem

0

像Tas指出的那樣,您需要使用工廠。但我認爲課堂上的簡單工廠功能就足夠了。

#include <iostream> 
#include <memory> 

template <class C> 
struct creator 
{ 
    template<typename... Args> 
    static std::unique_ptr<C> create(Args&&... args) 
    { return std::unique_ptr<C>(new C(std::forward<Args>(args)...)); } 
}; 

class MyClass : public creator<MyClass> 
{ 
private: 
    friend class creator<MyClass>; 
    MyClass(int) { std::cout << "Created"; } 
}; 

int main() 
{ 
    auto p = MyClass::create(0); 
    return 0; 
} 

既然你很可能不想重複自己,你可以創建一個有用的小模板Mixin(就像我上面做的那樣)。這將爲您節省爲每個班級輸入相同樣板代碼的工作,就像您所做的那樣。另一個好處是,使用該模板將爲您的應用程序中的所有類提供一致的界面和命名約定,這需要採用相同的方式。衆所周知,軟件中的一致性很好。

0

使析構函數保密,並提供刪除函數。這會使你的兩個陳述都起作用。

class T 
{ 
public: 
    void PrintMe(); 
    T(int a_, int b_, int c_); 
    void deleteMe() { delete this;} 
private: 
    ~T(){} 
    int a, b, c; 
};