overload operator cppreference c++ operator-overloading c++-faq

cppreference - overload operator c++



¿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 pila). (4)

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

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


En mi situación particular, si el bloqueo 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.


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 bloqueo RAII. Tengo un camino a través del código donde el bloqueo solo es necesario si se cumplen ciertas condiciones (es un reproductor de video, y solo necesito mantener el bloqueo durante mi ciclo de renderizado si tengo un video cargado y reproduciendo; si no hay nada cargado, No lo necesito). La capacidad de crear bloqueos 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 bloqueo.

es decir algo como esto:

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

Si solo pudiera crear bloqueos en la pila, 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();


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 pila de un objeto y solo permitir que se inicie con ''nuevo''?