2016-05-25 4 views
3

У меня есть вспомогательный класс для автономного мониторинга процесса, и, как это немного «огонь и забыть» механизм, большой ловушкой является то, что вы можете использовать его как это:Можете ли вы запретить локальное создание экземпляра класса?

MyClass с (процесса);

Но когда c выходит из сферы видимости, нить внутри останавливается и, очевидно, из нее не появляется никаких уведомлений.

Как вы должны сделать это так:

MyClass * с = новый MyClass (процесс);

и обрабатывать всю жизнь самостоятельно.

Есть ли простой, хороший способ запретить локальное создание экземпляра и разрешить только «новый» в C++?

Cheers!

Valmond

ответ

6

Вы можете сделать деструктор класса частного (и определить альтернативную функцию-члена для освобождения). Это запрещает любые экземпляры прямого экземпляра класса, позволяя создавать экземпляры только кучи (new).

ПРИМЕЧАНИЕ: это лучше, чем сделать конструкторы частными, поскольку объекты могут быть созданы напрямую, а не через функцию. Также есть только один деструктор, который нужно приватизировать, но может быть много конструкторов.

Для удаления, вы можете реализовать что-то вроде:

struct MyStruct 
{ 
    void free() 
    { 
     delete this; 
    } 

private: 
    ~MyStruct() {}; 

}; 

int main() 
{ 
    MyStruct* s = new MyStruct; 
    s->free(); 
} 
+0

Другим возможным решением (за исключением объявляя частных конструктора или деструктора методов) является использование смарт-указателей, объявив свой тип, как это: ЬурейеЕ станд :: unique_ptr PtrMyClass; Но это не изящный способ. – LmTinyToon

+0

Итак, я вызываю свой деструктор через функцию открытого участника, но как мне удалить? – Valmond

+0

Извините, я идиот, я просто делаю удаление (это) в функции публичного участника, приветствую и благодарю! – Valmond

4

Вы могли бы сделать конструктор приватным и затем позволить экземпляр через функцию друга, который всегда делает это с помощью новых

3

"Как вы должны это сделать ... new MyClass." Нет, это не то, как вы должны это делать. Это требует утечки памяти.

Лучше всего иметь

class MyClass { 
    MyClass(Process const&); 
public: 
    static std::unique_ptr<MyClass> make(Process const&); 
} 

Это действительно позволяет вызывающим абонентам писать MyClass c {process};.

Конечно, ни ваша идея для new MyClass, ни эта идея не являются абсолютной профилактикой. Оба указателя должны быть где-то сохранены. Хранение либо в функции-local std::unique_ptr<MyClass> вызывает ту же самую проблему, что и у вас изначально.

+0

Спасибо за ответ, но ваша реализация ограничивает использование нескольких экземпляров, верно? – Valmond

+0

@Valmond: Нет, совсем нет? На самом деле, если бы было одно экземпляр, тогда мы не сможем вернуть 'std :: unique_ptr '. Потому что, если мы дважды назовем «MyClass :: make()», мы получим два 'unique_ptr', которые, очевидно, не были бы уникальными, если бы они указали на один экземпляр. – MSalters

+0

@MrSalters Хорошо, спасибо, что выяснили мое недоразумение! – Valmond

Смежные вопросы