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 fonction
b :: 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 un
d * code> et d'un
B & code> par un
d & code> où
b < / code> est un Base accessible de
d 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'un
d code> à un accessible base
b code>, un
d code> à un
x code> pour lequel
d 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>