2010-10-06 26 views
6

Dites que j'ai une classe nommée Base et une classe dérivée de celle-ci appelée SuperBase. Étant donné que add prend dans un Base*, serait l'une de ces valables:Transmettre à la validité de classe de base

SuperBase *super = new SuperBase; 
bases.add(super); 

Ou

SuperBase *super = new SuperBase; 
bases.add((Base*)super); 
+0

Je ne trouve pas un bon titre pour la question, mais je pense que c'est mieux. – GManNickG

Répondre

9

Les premiers travaux aussi longtemps que SuperBase tire publiquement de Base, via une conversion implicite de dérivé à -base:

struct base { virtual ~base() {} }; 
struct derived : base {}; 

base* b = new derived; // okay 

le second fonctionne aussi bien, mais ne tient pas compte de la protection des Base:

struct derived : private base {}; // private base 

base* b = new derived; // not okay, base is private 
base* b = (base*)(new derived); // okay, but gross 

Si c'est private, vous ne devriez probablement pas jeter à elle.

+1

+1 pour un comportement indéfini – jmasterx

+0

Utilisez 'static_cast ' à la place d'un cast de style C '(Base *)' pour vous assurer que vous n'avez pas de comportement indéfini. –

+2

Mais ce n'est pas vrai! (Au moins en C++ 03). La distribution de style C vers une base inaccessible * est * garantie pour fonctionner correctement (c'est-à-dire comme si la base était accessible). Le pointeur résultant est un pointeur valide vers le sous-objet de classe de base de type 'Base' et il peut être utilisé en toute sécurité en tant que tel. C'est à dire. La distribution de type C n'est pas un 'reinterpret_cast' dans ce cas, mais plutôt un' static_cast' qui ignore la protection. C'est, bien sûr, encore une mauvaise pratique de programmation, car elle ignore la protection, mais elle «fonctionne». Pourquoi dites-vous que le comportement est indéfini? – AnT

1

Les deux sont valides - un enfant peut être utilisé dans un endroit où une référence/un pointeur vers un parent est attendu. C'est ce qu'on appelle le polymorphisme.

1

Les deux seraient valides, bien que la diffusion de type super à Base* ne soit pas nécessaire.