#cpp #классы
MyClass o; // error
MyClass * o = new MyClass; // ok
Ответы
Ответ 1
Конечно, можно. Закройте его деструктор (сделайте его private). Чтобы удалить выделенный динамически объект, вам придется написать отдельную функцию - например, друга или статический член - для удаления, вроде friend void destroy(MyClass* t) { delete t; } ... MyClass * o = new MyClass; ... destroy(o);Ответ 2
Если в первую очередь имеет значение сам факт создания в куче, и нет обязательного требования разрешать в клиентском коде запись вида new MyClass, то вместо сокрытия деструктора можно подойти с другой стороны жизненного цикла объекта и сделать приватным конструктор, предоставив соответствующую create-функцию или даже семейство функций: class MyClass { MyClass(); public: static MyClass* create() { return new MyClass; } }; Теперь, чтобы не забыть сделать delete объекта в нужный момент и не получить утечку памяти, разумно возвращать не сырой указатель, а std::unique_ptr. Функция изменится так: static std::unique_ptrcreate() { return std::unique_ptr (new MyClass); } Однако, если мы пойдём ещё дальше и заменим std::unique_ptr (new MyClass) на std::make_unique () для уменьшения накладных расходов, то получим ошибку компиляции: error: calling a private constructor of class 'MyClass' Возникает это из-за того, что мы пытаемся вызвать наш приватный конструктор по сути вне класса MyClass. Но это можно побороть следующим небольшим "хаком" - добавить приватный тип и использовать его в качестве дополнительного параметра для конструктора MyClass, при этом сам конструктор снова сделать публичным. Итоговый пример: class MyClass { class tag {}; // скрытый от внешнего кода тип public: MyClass(const tag&) {} static std::unique_ptr create() { return std::make_unique (tag()); } }; int main() { auto p = MyClass::create(); }
Комментариев нет:
Отправить комментарий