Назад к вопросам
Middle+
79
questionbank

Как можно ограничить создание объектов класса в динамической памяти (heap) пользователями этого класса?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Ограничить создание объектов класса в динамической памяти можно, сделав операторы new и delete приватными или защищенными.

  1. Приватные операторы new и delete: Это самый строгий способ. Только члены класса и дружественные функции (оператор new[] также нужно объявить приватным).

    class NoHeapAlloc {
    private:
        void* operator new(size_t size);
        void operator delete(void* ptr);
        // Можно также запретить операторы для массивов
        void* operator new[](size_t size);
        void operator delete[](void* ptr);
    
    public:
        NoHeapAlloc() = default;
        // ... другие члены класса
    };
    
    // Использование:
    // NoHeapAlloc* obj = new NoHeapAlloc(); // Ошибка компиляции
    
  2. Защищенные операторы new и delete: Позволяет создавать объекты в куче классам-наследникам, но запрещает делать это извне.

    class BaseNoHeapAlloc {
    protected:
        void* operator new(size_t size);
        void operator delete(void* ptr);
        void* operator new[](size_t size);
        void operator delete[](void* ptr);
    
    public:
        BaseNoHeapAlloc() = default;
        // ... другие члены класса
    };
    
    // Наследник может создавать в куче
    class DerivedCanAlloc : public BaseNoHeapAlloc {
    public:
        DerivedCanAlloc() : BaseNoHeapAlloc() {}
        // ...
    };
    
    // Использование:
    // BaseNoHeapAlloc* base_obj = new BaseNoHeapAlloc(); // Ошибка компиляции
    // DerivedCanAlloc* derived_obj = new DerivedCanAlloc(); // OK (если вызывается из члена/друга DerivedCanAlloc)
    
    // Извне все равно запрещено
    // BaseNoHeapAlloc* base_obj_ext = new BaseNoHeapAlloc(); // Ошибка компиляции
    // DerivedCanAlloc* derived_obj_ext = new DerivedCanAlloc(); // Ошибка компиляции (если не из члена класса)
    

В обоих случаях пользователь сможет создавать объекты только на стеке или как члены других классов:

// Правильное использование для NoHeapAlloc при приватных операторах new/delete
NoHeapAlloc obj_on_stack; // OK