Me gustaría saber si necesito escribir destructor en clases cuando ya no uso punteros crudos? Simplemente aumente los indicadores inteligentes.Smart pointers & destructor
Respuesta
Siempre debe considerar proporcionar un destructor. Lo usarías para liberar los recursos que tu clase tenga. A menudo, mis destructores de la clase smart_ptr están vacíos, pero no siempre. Las secuencias de archivos, las conexiones de bases de datos, etc. necesitan una limpieza adecuada.
Todas esas cosas se pueden limpiar envolviéndolas en una clase RAII, como un 'smart_ptr'. Con C++ 11, los destructores de clase deberían ser raros. –
@Mooing No es broma. Los punteros inteligentes/RAII reducen mucho mi código y mis destructores generalmente están vacíos. Se toman un tiempo para acostumbrarse, pero vale la pena aprenderlo con seguridad. – Aura
Boost punteros inteligentes por sí mismos no tienen nada que ver con la necesidad de un destructor. Todo lo que hacen es eliminar la necesidad de llamar a eliminar en la memoria asignada que están administrando de manera efectiva. Habiendo dicho eso, si antes de comenzar a usar punteros inteligentes todo lo que tenía en sus destructores eran llamadas para eliminar y eliminar [] liberando la memoria de los miembros de la clase asignados dinámicamente y ahora ha cambiado todos esos punteros a punteros inteligentes, podría probablemente solo cambien a un destructor vacío ya que ahora se limpiarán por sí mismos cuando salgan del alcance.
Sin embargo, si por alguna razón, tiene una clase que necesita limpieza (limpieza de archivos, sockets, otros recursos, etc.), deberá proporcionar un destructor para hacerlo.
Avísame si eso ayuda.
Todas esas cosas se pueden limpiar envolviéndolas en una clase RAII, como un 'smart_ptr'. Con C++ 11, los destructores de clase deberían ser raros. –
Cada tipo de recurso debe tener una clase RAII para administrar ese recurso. Si también tiene un puntero inteligente con semántica de copia profunda (bastante fácil de hacer), eso es todo lo que necesita para administrar sus recursos el 99.9% del tiempo. No sé por qué unique_ptr
no hace copias en profundidad, ni ningún puntero inteligente de refuerzo, pero si tiene esas dos cosas, no necesita escribir constructores de copia, mover constructores, operadores de asignación, operadores de asignación de movimiento, ni destructores. Puede o no tener que proporcionar otros constructores (incluido el constructor predeterminado), pero esos son cinco lugares menos para cometer errores.
#include <memory>
template<class Type, class Del = std::default_delete<Type> >
class deep_ptr : public std::unique_ptr<Type, Del> {
public:
typedef std::unique_ptr<Type, Del> base;
typedef typename base::element_type element_type;
typedef typename base::deleter_type deleter_type;
typedef typename base::pointer pointer;
deep_ptr() : base() {}
//deep_ptr(std::nullptr_t p) : base(p) {} //GCC no has nullptr_t?
explicit deep_ptr(pointer p) : base() {}
deep_ptr(pointer p, const typename std::remove_reference<Del>::type &d) : base(p, d) {} //I faked this, it isn't quite right
deep_ptr(pointer p, typename std::remove_reference<Del>::type&& d): base(p, d) {}
deep_ptr(const deep_ptr& rhs) : base(new Type(*rhs)) {}
template<class Type2, class Del2>
deep_ptr(const deep_ptr<Type2, Del2>& rhs) : base(new Type(*rhs)) {}
deep_ptr(deep_ptr&& rhs) : base(std::move(rhs)) {}
template<class Type2, class Del2>
deep_ptr(deep_ptr<Type2, Del2>&& rhs) : base(std::move(rhs)) {}
deep_ptr& operator=(const deep_ptr& rhs) {base::reset(new Type(*rhs)); return *this;}
template<class Type2, class Del2>
deep_ptr& operator=(const deep_ptr<Type2, Del2>& rhs) {base::reset(new Type(*rhs)); return *this;}
deep_ptr& operator=(deep_ptr&& rhs) {base::reset(rhs.release()); return *this;}
template<class Type2, class Del2>
deep_ptr& operator=(deep_ptr<Type2, Del2>&& rhs) {base::reset(rhs.release()); return *this;}
void swap(deep_ptr& rhs) {base::swap(rhs.ptr);}
friend void swap(deep_ptr& lhs, deep_ptr& rhs) {lhs.swap(rhs.ptr);}
};
Con esta clase (o una similar), ¡no necesita mucho!
struct dog {
deep_ptr<std::string> name;
};
int main() {
dog first; //default construct a dog
first.name.reset(new std::string("Fred"));
dog second(first); //copy construct a dog
std::cout << *first.name << ' ' << *second.name << '\n';
second.name->at(3) = 'o';
std::cout << *first.name << ' ' << *second.name << '\n';
second = first; //assign a dog
std::cout << *first.name << ' ' << *second.name << '\n';
}
Como se ha demostrado en http://ideone.com/Kdhj8
- 1. Ayuda con C Pointers
- 2. C++ Huffman Tree and Pointers
- 3. For-Each y Pointers en Java
- 4. Smart JScrollPane autoscrolling
- 5. Visual Studio Smart Sangrado?
- 6. vim smart tabbing
- 7. Smart Client vs Ext JS
- 8. Destructor crash
- 9. Destructor privado
- 10. destructor estático
- 11. destructor estática
- 12. D Analógico a C++ member-function-pointers, no necesariamente delegados
- 13. ¿std :: vector llama al destructor de punteros a los objetos?
- 14. Motor de plantilla Smart-like para Java?
- 15. reproducir sonidos en samsung smart tv
- 16. Smart Client Guidance = Prism? Vs 2010
- 17. Aplicación de fondo en Smart TV
- 18. Experiencias de Smart Client Software Factory
- 19. Smart JVM y JIT Micro-Optimizations
- 20. Samsung Smart TV, PlayDRM y HLS
- 21. Google Analytics y Samsung Smart TV Apps
- 22. PHP: destructor vs register_shutdown_function
- 23. Destructor en const char *
- 24. comportamiento de php destructor
- 25. C++ comportamiento destructor
- 26. defecto destructor virtual puro
- 27. Destructor en Objective-C++
- 28. Excepción en destructor
- 29. GCC comportamiento destructor
- 30. Stopping destructor se llama
Tal @simchona sabe algo que yo no, pero punteros inteligentes, no alivian la necesidad de la limpieza, que acaba de cambiar la forma (cuando) se produce. –
Estoy leyendo esta pregunta como, ¿aliméntelos y elimine la necesidad de escribir destructores en casi todos los casos? ¿Es eso correcto? – gymbrall
@ Sí, si tiene un puntero_profundo (o como se llame), entonces no necesita asignación/mover/destructor/constructores. (Aunque los constructores todavía pueden ser útiles a veces) –