2010-10-10 5 views
9

Supposons que j'ai deux classes:virtuel par défaut d'tor

class Base{}; 

class Derived: public Base{}; 

aucun n'a d'tor, dans ce cas, si je déclare sur les variables:

Base b; 
Derived d; 

mon compilateur produira pour me d'tors, ma question est, les tors d'b and d sera virtuel ou pas?

+0

double possible de [Destructeurs par défaut virtuel en C++] (http://stackoverflow.com/questions/827196/virtual-default-destructors-in-c) –

Répondre

10

ma question est, les d'TdR du b et d seront virtuels ou non

Non, ils ne le seront pas. Si vous voulez un destructor virtuel, vous devez définir vos propres, même si sa mise en œuvre est exactement la même que celle qui serait fournie par le compilateur:

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

ma question est, les d'TdR du b et d sera virtuel ou non

Réponse courte: NOPES!

3

Elles ne seront PAS virtuelles. Cependant, si vous avez déclaré (et défini) un dteur virtuel dans Base, alors le dteur du dérivé sera automatiquement virtuel. HTH.

6

Les Destructeurs de Base et Derived ne sera pas virtual . Pour faire un destructor virtual vous devez marquer explicitement en place:

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

En fait, il n'y a plus qu'une seule raison d'utiliser Destructeurs virtuels. C'est pour fermer l'avertissement gcc: "class 'Base' a des fonctions virtuelles mais un destructeur non virtuel". Tant que vous stockez toujours vos objets alloués dans un shared_ptr, vous n'avez vraiment pas besoin d'un destructeur virtuel. Voici comment:

#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; 
} 

Le shared_ptr va nettoyer correctement, sans la nécessité d'un destructor virtuel. Rappelez-vous, vous faudra besoin d'utiliser le shared_ptr si!

Bonne chance!

+1

@ Daniel: Vraiment? Will the shared_ptr nettoyer correctement? Pourriez-vous dans ce cas démontrer comment cet effet pourrait être mis en œuvre? –

+0

@Armen: shared_ptr utilise son propre destructeur pour supprimer l'instance Concrete. C'est ce qu'on appelle RAII dans la communauté C++. Mon conseil est que vous appreniez tout ce que vous pouvez sur RAII. Cela rendra votre codage C++ beaucoup plus facile lorsque vous utilisez RAII dans toutes les situations. –

+0

@Daniel: Je connais RAII, et je sais aussi que le destructeur shared_ptr peut éventuellement supprimer le px stocké quand pn atteint 0. Mais si px avait un pointeur de type statique vers Base et un pointeur de type dynamique vers Derived, alors Base a un virtual destructeur, cela entraînera un comportement indéfini. Corrigez-moi si je me trompe. –

2

Comment peuvent-ils être virtuels, sauf si vous faites explicitement virtuel

+0

raison @downvoter s'il vous plaît? –

1

Juste pour ajouter un exemple à 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 l'on utilise un shared_ptr comme celui-ci:

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

Ensuite, le destructeur de béton et le destructeur de base sont appelés à la destruction de l'objet.

Si l'on utilise un shared_ptr comme celui-ci:

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

seule la destructor de base est appelée sur la destruction de l'objet.

C'est 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; 
    } 

}