Pourquoi le code suivant est-il une erreur de covariance? N'est-ce pas GCC dit: p> t * code> covariant avec void * code> ...? invalid covariant return type for 'virtual int* Derived::foo()'
3 Réponses :
[CLASS.VIRTUAL] / P7, OFFACIQUE MINE: P>
Le type de retour d'une fonction primordiale doit être soit identique à le type de retour de la fonction remplacée ou covariant em> avec le classes des fonctions. Si une fonction
d :: f code> remplace une fonctionb :: f code>, les types de retour des fonctions sont covariants si elles satisfaire les critères suivants: p>
- Les deux sont des pointeurs à classes forts>, les deux sont des références de lvalue à classes forts>, ou les deux sont des références de rap, ou les deux classes strictes forts> [Note de bas de page omis] li>
- [...] li> ul> blockQuote>
des pages 294-5 de D & E : P>
AFERT Quelque compte de l'alternative, nous avons décidé de permettre Remplacement d'un
B * code> par und * code> et d'unB & code> par und & code> oùb < / code> est un Base accessible ded code>. De plus,const code> peut être ajouté ou soustraite partout où c'est sûr. Nous avons décidé de ne pas détendre les règles à permettre des conversions techniquement réalisables telles qu'und code> à un accessible baseb code>, und code> à unx code> pour lequeld code> a une conversion,int * code> àvoid * code>,double code> àint code>, etc. Nous avons senti que les avantages de permettant de telles conversions par le dépassement ne l'emporteraient pas la Coût de mise en œuvre et potentiel d'utilisateurs déroutants. P> blockQuote>
Serait bien si vous pouviez expliquer le "pourquoi" derrière cette conception.
@Mehrdad a ajouté une citation de D & E.
Lorsque je regarde le problème avec la covariance et les limites des espaces de noms en C ++, je peux discerner le raisonnement derrière l'objet et les paquets de Java.
La fonction de type de retour Covariant est lorsque, une classe dérivée fournit un type de retour plus spécifique / plus étroit pour une fonction remplacée. Le type de retour de classe dérivé est dit covarient.
int * n'est pas de type vide * alors que quelque chose comme celui-ci représente le type de retour Covariant: P>
struct Base {
virtual void *foo();
virtual Base* func();
};
struct Derived : Base {
// int *foo();
Derived* func(); //COVARIANT RETURN TYPE
};
Vous expliquez la définition de "covariance", l'OP demande "pourquoi".
La covariance entre 1. Manque de cohérence forte>. P> Le mode de covariance actuel est trivial de comprendre et ne crée pas de confusion. dans la 3ème hiérarchie de en cas de classes, retourner si qui ajoute jusqu'à confusion. P> p> void * code> et t * code> n'est pas autorisé car:
Imaginez simplement de Void * code> type de covariance est autorisé. Pour une étape de dérivation, c'est bien, mais cela créera une confusion. par exemple: p> struct double _ code>, l'utilisateur sera confus que même si double * code> à int * code> n'est pas possible, pourquoi le code est toujours compilé? Seulement après avoir vérifié le haut de la classe Void _ code>, il est connu qu'il est dû à double * code> à vide * code> est "Covariant". Les mêmes choses vont aussi pour le compilateur: -) p> B & code> / d * code> / dd * code> est possible. Mais la même chose n'est pas possible avec void & code> et donc int & code> etc. P> vide * code> est autorisé, alors suivi est également autorisé de manière non intentionnelle. P>