Sobes.tech
Middle+
178

¿Cómo se puede limitar la creación de objetos de la clase en la memoria dinámica (heap) por parte de los usuarios de esa clase?

Respuesta de la IA

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