¿Es posible evitar la asignación de pila de un objeto y solo permitir que se inicie con 'nuevo' en el montón?¿Es posible evitar la asignación de apilamiento de un objeto y solo permitir que se lo instancia con 'nuevo'?
Respuesta
Una forma de hacerlo sería convertir los constructores en privados y solo permitir la construcción a través de un método estático que devuelva un puntero. Por ejemplo:
class Foo
{
public:
~Foo();
static Foo* createFoo()
{
return new Foo();
}
private:
Foo();
Foo(const Foo&);
Foo& operator=(const Foo&);
};
+ 1 para recordar hacer que no se pueda copiar. –
O mejor aún una función estática que devuelve un std :: unique_ptr
** Pregunta relacionada: ** [¿Cómo evito que se asigne una clase a través del operador 'nuevo'? (Me gustaría asegurar que mi clase RAII esté siempre asignada en la pila.)] (Http://stackoverflow.com/questions/124856/how-do-i-prevent-a-class-from-being-allocated- via-the-new-operator-id-like) –
Puede hacer el constructor private
, luego proporcione un método de fábrica estático public
para crear los objetos.
Se puede crear un archivo de cabecera que proporciona una interfaz abstracta para el objeto y las funciones de la fábrica que devuelven punteros a objetos creados en el montón.
// Header file
class IAbstract
{
virtual void AbstractMethod() = 0;
public:
virtual ~IAbstract();
};
IAbstract* CreateSubClassA();
IAbstract* CreateSubClassB();
// Source file
class SubClassA : public IAbstract
{
void AbstractMethod() {}
};
class SubClassB : public IAbstract
{
void AbstractMethod() {}
};
IAbstract* CreateSubClassA()
{
return new SubClassA;
}
IAbstract* CreateSubClassB()
{
return new SubClassB;
}
En el caso de C++ 11
class Foo
{
public:
~Foo();
static Foo* createFoo()
{
return new Foo();
}
Foo(const Foo &) = delete; // if needed, put as private
Foo & operator=(const Foo &) = delete; // if needed, put as private
Foo(Foo &&) = delete; // if needed, put as private
Foo & operator=(Foo &&) = delete; // if needed, put as private
private:
Foo();
};
Como Scott Meyers declaró en "Elemento 11: Prefiere las funciones eliminadas a las indefinidas privadas". En su libro "Effective Modern C++", es mejor declarar las funciones de miembros eliminadas 'public'. --QUOTE-- "Por convención, las funciones eliminadas se declaran' públicas', no 'privadas'. Hay una razón para eso. Cuando el código del cliente intenta usar una función miembro, C + + verifica la accesibilidad antes de eliminar el estado. Cuando el código del cliente intenta usar una función 'privada 'eliminada, algunos compiladores se quejan solo de que la función es' privada', aunque la accesibilidad de la función realmente no afecta si se puede usar. –
--QUOTE-- "Vale la pena tener esto en cuenta al revisar el código heredado para reemplazar las funciones de miembro' privadas' y no definidas con las eliminadas, porque hacer que las nuevas funciones sean 'públicas' generalmente dará como resultado mejores mensajes de error. " –
Deba. Dar. Moar. Arriba. Votos. – kevinarpe
El siguiente permite constructores públicos y se detendrá asignaciones de pila lanzando en tiempo de ejecución. La nota thread_local
es una palabra clave C++ 11.
class NoStackBase {
static thread_local bool _heap;
protected:
NoStackBase() {
bool _stack = _heap;
_heap = false;
if (_stack)
throw std::logic_error("heap allocations only");
}
public:
void* operator new(size_t size) throw (std::bad_alloc) {
_heap = true;
return ::operator new(size);
}
void* operator new(size_t size, const std::nothrow_t& nothrow_value) throw() {
_heap = true;
return ::operator new(size, nothrow_value);
}
void* operator new(size_t size, void* ptr) throw() {
_heap = true;
return ::operator new(size, ptr);
}
void* operator new[](size_t size) throw (std::bad_alloc) {
_heap = true;
return ::operator new[](size);
}
void* operator new[](size_t size, const std::nothrow_t& nothrow_value) throw() {
_heap = true;
return ::operator new[](size, nothrow_value);
}
void* operator new[](size_t size, void* ptr) throw() {
_heap = true;
return ::operator new[](size, ptr);
}
};
bool thread_local NoStackBase::_heap = false;
No creo que necesite '_stack' como miembro de datos. Tenerlo como una simple variable de pila dentro del constructor 'NoStackBase' debería hacer. –
Tampoco es necesario que el destructor sea 'virtual'. Nadie puede eliminar una clase derivada a través de 'NoStackBase' de todos modos. –
- 1. ¿Es posible eliminar un objeto no nuevo?
- 2. ¿Permitir solo una instancia de script python?
- 3. ¿Es posible evitar que un método se muestre en intellisense?
- 4. ¿Cómo se actualiza parcialmente un objeto en MongoDB por lo que el nuevo objeto se superpondrá/fusionarse con la existente
- 5. Escapar solo lo necesario, ¿es eso posible?
- 6. ¿Es posible sobrecargar la asignación de Python?
- 7. En Java, ¿lo nuevo siempre es nuevo?
- 8. ¿Es posible evitar que se guarde un archivo php que tenga un error de análisis?
- 9. ¿Cuál es la mejor manera de solo permitir que se incluya un archivo PHP?
- 10. Estructura de la memoria de un objeto que solo funciona?
- 11. TinyMCE: ¿es posible limitar solo para permitir viñetas?
- 12. En C++, ¿por qué se necesita `nuevo` para crear dinámicamente un objeto en lugar de asignación?
- 13. ¡La asignación de la pila falla y la asignación del montón tiene éxito! ¿Es posible?
- 14. Regex permitir dígitos y un solo punto
- 15. ¿Es posible recuperar la instancia del objeto realizando una llamada a un método con AspectJ?
- 16. ¿Cómo imprimir lo que creo que es un objeto?
- 17. En Delphi es posible vincular una interfaz a un objeto que no lo implementa
- 18. ¿Cuál es la ventaja de llamar a alguien nuevo en una instancia de objeto?
- 19. Instancia es un "objeto", pero la clase no es una subclase de "objeto": ¿cómo es esto posible?
- 20. obtener posible instancia/tipo de objeto
- 21. ¿Es posible escribir el operador de asignación de constructor solo mencionando miembros con copia especial?
- 22. ¿Cuál es la diferencia entre una instancia y un objeto?
- 23. ¿Es posible cambiar la clase de un objeto Ruby?
- 24. Evitar el apilamiento de perros o la manada atronadora en un escenario de caducidad de memcached
- 25. Lo que define un objeto de negocio
- 26. Robots.txt: permitir solo mayor SE
- 27. ¿Cómo se permite ejecutar solo una instancia de un programa Java a la vez?
- 28. lo que es más caro para la memoria. "crear y eliminar objetos" o "reutilizar un objeto"?
- 29. ¿Puedo evitar la asignación de objetos?
- 30. ¿Es posible rastrear asignación/desasignación?
El inverso, que también puede ser interesante para los lectores: http://stackoverflow.com/questions/10985/how-to-prevent-an-object-being-created-on-the-heap – kevinarpe