2010-08-10 2 views
1

Je n'ai jamais vu une classe utilisée comme base virtuelle et non virtuelle (c'est-à-dire si une classe est destinée à être un ancêtre alors nous connaissons habituellement à l'avance le type d'héritage - virtuel ou non virtuel). Donc je suppose qu'il y a une liberté sujette aux erreurs dans C++ pour spécialiser l'héritage "virtuel" dans la liste des classes de base. Il devrait être préférable de spécifier comme "virtuel" la classe de base elle-mêmeest la liste de classe de base le bon endroit pour indiquer l'héritage virtuel?

Ou peut-être que je me trompe? Si non, quelqu'un peut-il décrire certaines techniques pour empêcher l'héritage accidentel non virtuel pour une telle classe "virtuelle"?

Ou y a-t-il des perspectives dans les prochains standards C++?

(Désolé si double)


Quelques exemples

1) ReferenceCounted classe comme base pour toutes les classes que certains à base de compte pointeur intelligent référence peut pointer. Nous devons empêcher les doublons de ces instances de base (et des compteurs de référence). Il n'y a aucune raison d'utiliser cette classe comme base non virtuelle, sauf pour l'optimisation.

2) Une hiérarchie d'interfaces et correspondant hiérarchie des implémentations (hiérarchie des interfaces doit être « virtuelle » dans ce cas)

 
// interfaces: 

struct BaseIface{ 
    void virtual func()=0; 
}; 

struct DerivedIface: public virtual BaseIface{ 
    void some_another_func()=0; 
} 


// implementations 

class BaseImpl: public virtual BaseIface{ 
    void virtual func(){....}; 
} 

class DerivedImpl: public BaseImpl, public virtual DerivedIface{ 
    void some_another_func(){...}; 
} 

Je soupçonne que, dans bien des cas, l'héritage nonvirtual n'est pas un besoin conceptuel, il Utilisé uniquement pour réduire la surcharge d'héritage virtuel (et parfois pour une capacité à static_cast <> à piloter :)

Notez que Java utilise uniquement l'héritage virtuel (en termes de C++) pour les interfaces, et je ne connais aucune plainte que cette langue manque de "non virtuel" (c'est esentiellement langage moins expressif que C++ mais cette "fonctionnalité" n'est pas sa faute principale :).

Répondre

1

Il n'y a pas vraiment moyen de le faire dans la classe de base (et vous ne le voudriez pas vraiment). Il est parfaitement raisonnable d'utiliser une classe de base pour l'héritage virtuel et non virtuel. Ce que vous voudriez vraiment comme serait de spécifier l'héritage virtuel dans la classe la plus dérivée, où actuellement doit être spécifié dans les classes intermédiaires. Malheureusement, je ne vois pas beaucoup de choses là-dessus - même si l'héritage virtuel devient nécessaire (principalement) quand une classe dérive de deux (ou plus) autres classes ayant chacune une base commune, l'héritage virtuel gouverne vraiment la façon dont ces deux autres Les classes sont compilées, donc si vous (seulement) l'avez spécifié dans la classe la plus dérivée, vous finirez avec quelque chose comme export, où vous devrez peut-être revenir en arrière et recompiler ces classes intermédiaires en fonction de la classe la plus dérivée spécifiant héritage virtuel (et avoir un moyen de stocker les classes intermédiaires compilées dans les deux sens, car il peut être utilisé dans les deux sens).

+0

Vous venez de décrire des problèmes avec l'héritage virtuel « paresseux » et la solution est à utiliser « nonlazy » un, par exemple pour définir « virtuelle » pour la plupart base (non plus dérivée) classe Cependant, je devrais probablement mieux expliquer mon intention, alors j'ai ajouté quelques exemples à ma question. – user396672

Questions connexes