2016-04-03 18 views
-2
ben şöyle class T 'ın düzenli kurucuları çağırarak yasakla gerekir

olarak:kullanın yeni() C++ yapıcısı

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

C++ mümkün müdür? Sen kullanarak tür davranışı taklit edebilir

+4

Neden bu ihtiyacım var? Ayrıca, kaynak sızıntılarının kapsamını azaltmak ve istisna güvenliğini artırmak için 'unique_ptr ' döndürmeyi düşünün. – juanchopanza

+5

Nesne oluşturmayı statik yönteme veya fabrika sınıfına kapatabilirsiniz. – soon

+1

Her iki yol da aynı kurucuyu çağırıyor, böylece ne yaparsanız yapın onu asla uygulayamayacaksınız. – Joe

cevap

2

bir factory pattern: Bir nesnenin örneklerini örnekleme kullanılan bir friend class:

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

Şimdi
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}}; 
} 

kullanıcılar artık doğrudan sınıf oluşturabiliriz

Ve bunun yerine yalnızca aşağıdaki kullanabilirsiniz:

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

Ancak, sadece bir XY problem sahip olabileceğini unutmayın. Gibi Tas işaret

0

, bir fabrika kullanmak gerekir. Ama bence sınıftaki basit bir fabrika işlevi yeterli.

#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; 
} 

büyük olasılıkla kendini tekrarlamak istemiyorum olduğundan, (yukarıda yaptığım gibi) Mixin şablonlu bir yararlı küçük oluşturabilirsiniz. Bu, yaptığınız gibi her sınıf için aynı klişe kodu yazarak çalışmalarını kurtaracak. Ek bir avantaj, şablonu kullanmanın, uygulamanızdaki tüm sınıflar arasında tutarlı bir arayüz ve adlandırma kuralı sağlaması ve aynı şekilde davranması gerekir.
Ve tutarlılık, hepimizin bildiği gibi, yazılımda iyidir.

0

Yap yıkıcı özel bir silme fonksiyonu sağlarlar. Bu, her iki ifadeniz de işe yarar.

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