2012-05-11 15 views
5

Załóżmy, że mam klasę z metody fabrykiPrevent instancji obiektu poza jego metody fabryki

class A { 
public: 
    static A* newA() 
    { 
    // Some code, logging, ... 
    return new A(); 
    } 
} 

Czy to możliwe, aby zapobiec instancji obiektu tej klasy z new, tak że metoda fabrycznym jest jedyna metoda tworzenia instancji obiektu?

+2

Singletons są złe. Zobacz tutaj: http://programmers.stackexchange.com/questions/40373/so-singletons-are-bad-then-what –

+2

@Truth: To nie wygląda jak singleton. –

+0

@OliCharlesworth: Fabryka, która zwraca instancję samego siebie i uniemożliwia innym tworzenie jej? Wygląda niebezpiecznie blisko. –

Odpowiedz

8

Pewnie; po prostu zrobić prywatnej konstruktora (chronione, jeśli jest to klasa bazowa):

class A { 
public: 
    static A* newA() 
    { 
    // Some code, logging, ... 
    return new A(); 
    } 

private: 
    A() {} // Default constructor 
}; 

Należy dokonać konstruktor kopia private/chroniony, a także, jeśli jest to wymagane.

Jak zwykle należy zdecydowanie rozważyć zwrot wskaźnika inteligentnego zamiast wskaźnika surowego, aby uprościć problemy z zarządzaniem pamięcią.

+0

Ta odpowiedź tylko krzyczy z 'std :: unique_ptr' ... Edit: Meh, nie zmieniaj swojej odpowiedzi na ducha. : P – Xeo

+0

Dziękuję za odpowiedź. Co do inteligentnych wskaźników - wiem. Normalnie ich używałbym. Ale zarządzanie pamięcią dla tego obiektu jest nieco skomplikowane i nie może używać 'shared_ptr'everywhere ze względu na wydajność. – Tibor

+0

Zawsze się zastanawiałem, przypuśćmy, że twoja fabryka zwraca wartość unique_ptr , ale faktycznie chce on shared_ptr (lub vice versa), jak by to zrobić? – stijn

3

Można też dokonać konstruktora kopii prywatnej, jak również z nowym lub C++ 11 składni można jednoznacznie powiedzieć, że kompilator nie skopiować go i uczynić z domyślnego konstruktora prywatny coś takiego:

struct NonCopyable { 
    NonCopyable & operator=(const NonCopyable&) = delete; 
    NonCopyable(const NonCopyable&) = delete; 
    NonCopyable() = default; 
}; 

class A : NonCopyable { 
public: 
    static std::shared_ptr<A> newA() 
    { 
    // Some code, logging, ... 
    return std::make_shared<A>(); 
    } 

private: 
    A() {} // Default constructor 
}; 

C++ 03 droga była zazwyczaj coś takiego:

class A { 
public: 
    static A* newA() 
    { 
    // Some code, logging, ... 
    return new A(); 
    } 

private: 
    A() {}      // no outsider default constructor 
    A(const A& rhs);    // no copy 
    A& operator=(const A& rhs); // no assignment 
}; 

int main() 
{ 
    A x;  // C2248 
    A y(x);  // C2248 
    x = y;  // C2248 
    A* p = A::newA(); // OK 
    std::cin.get(); 
    return 0; 
} 
+0

Z C++ 11 naprawdę powinieneś unikać zwracania gołego wskaźnika. –

+0

Słusznie, chciałbym uniknąć większości tego i po prostu użyć 'std :: unique_ptr' w większości przypadków prawdopodobnie. – AJG85

Powiązane problemy