¿Cómo evito que se asigne una clase a través del operador ‘nuevo’? (Me gustaría asegurar que mi clase RAII siempre esté asignada en la stack).

Me gustaría asegurar que mi clase RAII siempre esté asignada en la stack.

¿Cómo evito que se asigne una clase a través del operador ‘nuevo’?

Todo lo que necesita hacer es declarar privado al nuevo operador de la clase:

class X { private: // Prevent heap allocation void * operator new (size_t); void * operator new[] (size_t); void operator delete (void *); void operator delete[] (void*); // ... // The rest of the implementation for X // ... }; 

Hacer que el ‘operador nuevo’ sea privado impide de manera efectiva que el código fuera de la clase use ‘nuevo’ para crear una instancia de X.

Para completar las cosas, debe ocultar ‘operator delete’ y las versiones de arreglos de ambos operadores.

Desde C ++ 11 también puede eliminar explícitamente las funciones:

 class X { // public, protected, private ... does not matter static void *operator new (size_t) = delete; static void *operator new[] (size_t) = delete; static void operator delete (void*) = delete; static void operator delete[](void*) = delete; }; 

Pregunta relacionada: ¿Es posible evitar la asignación de stack de un objeto y solo permitir que se inicie con ‘nuevo’?

No estoy convencido de tu motivación.

Hay buenas razones para crear clases de RAII en la tienda gratuita.

Por ejemplo, tengo una clase de locking RAII. Tengo un camino a través del código donde el locking solo es necesario si se cumplen ciertas condiciones (es un reproductor de video, y solo necesito mantener el locking durante mi ciclo de renderizado si tengo un video cargado y reproduciendo; si no hay nada cargado, No lo necesito). La capacidad de crear lockings en la tienda gratuita (con un scoped_ptr / auto_ptr) es, por lo tanto, muy útil; me permite usar la misma ruta de código independientemente de si tengo que sacar el locking.

es decir algo como esto:

 auto_ptr l; if(needs_lock) { l.reset(new lock(mtx)); } render(); 

Si solo pudiera crear lockings en la stack, no podría hacer eso …

@DrPizza:

Ese es un punto interesante que tienes. Sin embargo, tenga en cuenta que hay algunas situaciones en las que el modismo RAII no es necesariamente opcional.

De todos modos, tal vez una mejor manera de abordar su dilema es agregar un parámetro al constructor de su cerradura que indique si es necesario o no. Por ejemplo:

 class optional_lock { mutex& m; bool dolock; public: optional_lock(mutex& m_, bool dolock_) : m(m_) , dolock(dolock_) { if (dolock) m.lock(); } ~optional_lock() { if (dolock) m.unlock(); } }; 

Entonces podrías escribir:

 optional_lock l(mtx, needs_lock); render(); 

En mi situación particular, si el locking no es necesario, el mutex ni siquiera existe, por lo que creo que sería mucho más difícil ajustarlo.

Creo que lo que realmente estoy luchando por comprender es la justificación para prohibir la creación de estos objetos en la tienda gratuita.