2010-10-10 8 views
9

Supongamos que tengo dos clases:virtual predeterminado d'tor

class Base{}; 

class Derived: public Base{}; 

tiene ninguna d'tor, en este caso si yo anuncio acerca de las variables:

Base b; 
Derived d; 

mi compilador creará para me d'tors, mi pregunta es, ¿los valores predeterminados de b and d serán virtuales o no?

+0

posible duplicado de [Destructors predeterminados virtuales en C++] (http://stackoverflow.com/questions/827196/virtual-default-destructors-in-c) –

Respuesta

10

mi pregunta es, los d'tores de la B y D serán virtuales o no

No, no lo harán. Si quieres un destructor virtual, tendrá que definir su propia, aunque su aplicación es exactamente el mismo que el que se suministra por el compilador:

class Base { 
    public: 
    virtual ~Base() {} 
}; 
5

mi pregunta es, los d'tores de la B y D será virtual o no

Respuesta corta: Nopes!

3

NO serán virtuales. Sin embargo, si declaras (y defines) un dtor virtual en Base, entonces el dtor derivado será automáticamente virtual. HTH.

6

Los destructores de Base y Derived no será virtual . Para hacer un destructor virtual que necesita para marcarlo de forma explícita:

struct Base 
{ 
    virtual ~Base() {} 
}; 

En realidad ahora hay una sola razón para usar destructores virtuales. Eso es para cerrar la advertencia de gcc: "clase 'Base' tiene funciones virtuales pero destructor no virtual". Siempre que siempre almacene sus objetos asignados en un shared_ptr, entonces realmente no necesita un destructor virtual. Así es como:

#include <iostream> // cout, endl 
#include <memory>  // shared_ptr 
#include <string>  // string 

struct Base 
{ 
    virtual std::string GetName() const = 0; 
}; 

class Concrete : public Base 
{ 
    std::string GetName() const 
    { 
     return "Concrete"; 
    } 
}; 

int main() 
{ 
    std::shared_ptr<Base> b(new Concrete); 
    std::cout << b->GetName() << std::endl; 
} 

El shared_ptr va a limpiar correctamente, sin la necesidad de un destructor virtual. Recuerde, usted tendrá ¡necesitará usar el shared_ptr!

¡Buena suerte!

+1

@ Daniel: De Verdad? ¿El shared_ptr limpiará correctamente? ¿Podría por favor en este caso demostrar cómo se podría implementar ese efecto? –

+0

@Armen: shared_ptr usa su propio destructor para eliminar la instancia de Concrete. Esto se conoce como RAII dentro de la comunidad C++. Mi consejo es que aprendas todo lo que puedas sobre RAII. Hará que su codificación en C++ sea mucho más fácil cuando use RAII en todas las situaciones. –

+0

@Daniel: sé de RAII, y también sé que eventualmente el destructor shared_ptr puede eliminar la px almacenada cuando pn llega a 0. Pero si px tiene un puntero de tipo estático a Base y un puntero de tipo dinámico a Derived, entonces a menos que Base tenga una virtual destructor, esto dará como resultado un comportamiento indefinido. Corrígeme si estoy equivocado. –

2

¿Cómo pueden ser virtuales a menos que haga explícitamente como virtuales

+0

@downvoter reason por favor? –

1

Sólo para añadir un ejemplo más de Daniel Lidström's answer

As long as you always store your allocated objects in a shared_ptr, then you really don't need a virtual destructor.

Si se utiliza un shared_ptr así:

std::shared_ptr<Base> b(new Concrete); 

A continuación, se invoca el destructor de hormigón y el destructor de base para destruir el objeto.

Si se utiliza un shared_ptr así:

Base* pBase = new Concrete; 
std::shared_ptr<Base> b(pBase); 

Sólo entonces el destructor base se denomina en la destrucción del objeto.

Esto es an example

#include <iostream> // cout, endl 
#include <memory>  // shared_ptr 
#include <string>  // string 

struct Base 
{ 
    virtual std::string GetName() const = 0; 
    ~Base() { std::cout << "~Base\n"; } 
}; 

struct Concrete : public Base 
{ 
    std::string GetName() const 
    { 
     return "Concrete"; 
    } 
    ~Concrete() { std::cout << "~Concrete\n"; } 
}; 

int main() 
{ 
    { 
    std::cout << "test 1\n"; 
    std::shared_ptr<Base> b(new Concrete); 
    std::cout << b->GetName() << std::endl; 
    } 

    { 
    std::cout << "test 2\n"; 
    Base* pBase = new Concrete; 
    std::shared_ptr<Base> b(pBase); 
    std::cout << b->GetName() << std::endl; 
    } 

} 
Cuestiones relacionadas