10
votes

Se débarrasser de l'erreur C2243

est-il possible de se débarrasser de Erreur C2243 ? Xxx

J'ai eu cette erreur dans mon application et à la fin, j'ai réussi à la compiler en faisant une conversion explicite: xxx

i peut 'T Comprendre pourquoi en faisant de la classe D héritée de protéger de B rend la conversion implicite inaccessible.

J'ai essayé d'éviter la conversion explicite en créant un opérateur B () dans la classe D afin de rendre la conversion accessible: xxx

mais il n'y a pas de manière.

toute autre solution pour éviter une conversion explicite?


0 commentaires

6 Réponses :


8
votes

car protégé code> et héritage privé code> ne sont pas is-a code> relation, ils ne sont que du sucre de syntaxe pour la composition. Vos cours peuvent être réécrites exactement comme celui-ci, mais vous perdez la commodité de laisser le compilateur définir B code> pour vous et d'utiliser des membres B directement au lieu de vous en faire référence explicitement:

B *p = reinterpret_cast<B*>(&d); // TOTALLY WRONG, although it compiles :)


0 commentaires

18
votes

Si vous souhaitez autoriser la conversion, vous devez utiliser l'héritage public.

Utilisation de l'héritage protégé ou privé, vous déclarez que le fait que le type dérivé hérite de la classe de base est un détail qui ne doit pas être visible de l'extérieur: c'est pourquoi vous obtenez cette erreur.

Vous devez considérer l'héritage non public seulement comme une forme de composition avec la possibilité supplémentaire de remplacer les méthodes.


2 commentaires

Qu'en est-il de donner accès à l'interface Const de la classe de base? Alors hériter de manière privée et permettant de se lancer à Const Base &? Demander parce que ne peut pas le faire fonctionner sur MSVC ...


Il suffit de répondre à moi-même, vous devez gérer la classe par agrégation et non héritage, sinon MSVC est confondu et tente de résoudre la conversion par héritage privé (cacher l'opérateur de distribution)



2
votes

Par suite des enfants D et DS, personne ne sait qu'ils sont parents parent, vous devez donc le faire explicitement.

C'est ce que signifie son héritage protégé, seule votre famille (enfants) saura que vous hériter. Et vous pouvez l'utiliser, par exemple dans une méthode pour enfants, une conversion implicite serait légale.

Si vous voulez avoir une conversion implicite de vos enfants, vous devez le rendre public pour que tout le monde sache.


0 commentaires

0
votes

Avez-vous essayé de faire de l'opérateur B () public dans la classe D? Dans le code que vous avez montré, il serait marqué protégé et toujours inaccessible. Mais j'éviterais les opérateurs de conversion en général si possible.

Néanmoins, héritage de B Protégé B signifie que vous avez l'intention d'éviter de faire B * P = & D. Imaginez si B était en fait une variable d'élément protégé au sommet de D. Tout comme si vous ne pouvez pas accéder à D.B dans ce cas, vous ne pouvez pas accéder à D en tant que B *, à moins que vous ne le jetaiez.

donc hériter B publiquement ou utilisez vos mises. J'irais avec héritage B publiquement, car la héritage de son protégé dit essentiellement «Ne m'utilisez pas comme un B», que vous essayez de faire de toute façon.


0 commentaires

2
votes

Le problème ici est que vous essayez de faire une fin de course autour des informations qui cachent que l'attribut protégé protégé fournit. Si vous souhaitez accéder à une instance de D en tant que B, pourquoi l'avez-vous héritée aussi protégée que public? Ce que vous dites dans l'utilisation d'une héritage protégé, c'est que vous ne souhaitez que les instances de D et ses descendants sont au courant de la composante B. Vous devez rejouer à nouveau ce que vous voulez accomplir.

L'ancienne Cast de style C que vous utilisez n'a aucune de la subtilité des moulages récents C ++, ce qui vous donne du code qui compilera, mais le problème est vraiment dans l'héritage.


0 commentaires

0
votes

Parce que personne dehors ne sait qu'elles sont parent-enfant, vous ne pouvez effectuer que cette action dans la classe dérivée de s. C'est un exemple (test dans Visual Studio 2013):

class BASE{};

class BASE1 :protected BASE{};

class BASE2 :protected BASE1
{
public:
    void func(BASE &a, BASE1 &b){a = b;}
};

void main()
{
    BASE a;
    BASE1 b;
    BASE2 c;

    c.func(a, b);;
    system("pause");
 }


0 commentaires