web-dev-qa-db-fra.com

Abaissement de l'héritage C ++

J'ai ma classe de base comme suit:

class point    //concrete class
{
 ...    //implementation
}

class subpoint : public point  //concrete class
{
...     //implementation
}

Comment convertir un objet point en un objet sous-point? J'ai essayé les trois éléments suivants:

point a;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
subpoint b = (subpoint)a;

Quel est le problème avec ces moulages?

16
CodeKingPlusPlus

Comment convertir un objet point en un objet sous-point?

Tu ne peux pas; sauf si point a un opérateur de conversion, ou subpoint a un constructeur de conversion, auquel cas les types d'objets peuvent être convertis sans besoin de transtypage.

Vous pouvez convertir un pointréférence (ou pointeur) en subpointréférence (ou pointeur), si l'objet référencé était en fait de type subpoint:

subpoint s;

point & a = s;
subpoint & b1 = static_cast<subpoint&>(a);
subpoint & b2 = dynamic_cast<subpoint&>(a);

La première (static_cast) est plus dangereux; il n'y a aucune vérification que la conversion est valide, donc si a ne fait pas référence à un subpoint, alors en utilisant b1 aura un comportement indéfini.

La deuxième (dynamic_cast) est plus sûr, mais ne fonctionnera que si point est polymorphe (c'est-à-dire s'il a une fonction virtuelle). Si a fait référence à un objet de type incompatible, il lèvera une exception.

30
Mike Seymour

Le but d'une distribution dynamique est de "vérifier au moment de l'exécution si un objet est d'un certain type dans la hiérarchie". Voyons maintenant ce que vous avez:

  1. Vous avez un objet ponctuel. Pas un sous-point.
  2. Vous demandez une distribution dynamique si l'objet est un sous-point. Ce n'est pas.
  3. Parce que ce n'est pas un sous-point, dynamic_cast échoue - sa façon de vous dire que l'objet n'est pas le type vers lequel vous essayez de le caster.

En revanche, cela aurait fonctionné:

subpoint c;
point *a = &c;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
5
Carl

Pour le premier exemple, dynamic_cast Ne fonctionne que s'il y a au moins une méthode virtuelle dans la classe de base. Et si l'objet n'est pas réellement du type que vous essayez de caster, il en résultera NULL.

Pour le deuxième exemple, vous avez besoin de &a Au lieu de a, mais une fois que vous aurez corrigé ce problème, vous obtiendrez un comportement indéfini car le type d'objet est incorrect.

Le troisième exemple nécessite une méthode operator subpoint() dans point pour effectuer une conversion lors de la création d'une copie.

3
Mark Ransom

Dans l'ensemble, cela ne fonctionnera pas car point n'est pas un subpoint; seul l'inverse est vrai. Cependant, il existe également d'autres problèmes.

En ordre:


subpoint* b = dynamic_cast<subpoint*>(&a);

dynamic_cast Ne fonctionne que sur les types polymorphes, c'est-à-dire les types qui déclarent au moins une fonction virtuelle. Je suppose que point n'a pas de fonctions virtuelles, ce qui signifie qu'il ne peut pas être utilisé avec dynamic_cast.


subpoint* b = (subpoint*)a;

Pour que cette conversion fonctionne, point doit déclarer un opérateur de conversion en subpoint *, Par exemple, point::operator subpoint *().


subpoint b = (subpoint)a;

Pour que cette conversion fonctionne, le point doit déclarer un opérateur de conversion en subpointosubpoint doit avoir un constructeur qui accepte un paramètre convertible de point.

2
MSN

Quel est le problème avec ces moulages?

Le fait que vous tentiez de les faire. Un point n'est pas un subpoint, je serais surpris si cela fonctionnait.

1
Luchian Grigore

a ne peut pas être transformé en subpoint. cette implémentation n'est pas là.

0
Daniel A. White