Question

Voici mon code -

#include<iostream>
using namespace std;

class base
{
public:
    void sid()
    {
    }  
};

class derived : private base
{
public:
    void sid()
    {
    }
};

int main()
{
    base * ptr;
    ptr = new derived; // error: 'base' is an inaccessible base of 'derived'
    ptr->sid();
    return 0;
}

Cela donne une erreur de compilation.

error: 'base' is an inaccessible base of 'derived'

Étant donné que le compilateur va essayer appeler la classe de base sid() pourquoi dois-je obtenir cette erreur? Quelqu'un peut-il s'il vous plaît expliquer.

Était-ce utile?

La solution

11.2 $ / 4 états -

  

Une classe de base B de N est accessible à R, si

     
      
  • un membre du public a inventé de B serait un membre de public N, ou
  •   
  • R se produit dans un organe ou un ami de la classe N, et un public inventé   membre B serait un privé ou   membre protégé de N, ou
  •   
  • R se produit dans un organe ou un ami d'une classe P dérivé de N, et un   inventé membre public de B serait   membre privé ou protégé de P, ou
  •   
  • il existe une classe S tel que B est une classe de base de S accessible à R   et S est une classe de base de N accessibles   à R ".
  •   

Ici, 'B' est 'base', 'N' est 'dérivés' et 'R' est principal.

  1. Considérez la 2ème-balles R se produit dans un membre ou un ami d'une classe N, .... Cette clause ne concerne pas 'R' (principal) est ni membre ni ami de 'N' (dérivé)

  2. Considérez le 3-balles « R se produit dans un membre ou un ami d'une classe P .... ». Cette claus ne s'applique pas pour les mêmes raisons que ci-dessus

  3. Considérez le 4 Encore une fois cette-balles clause ne s'applique pas

Nous pouvons donc conclure que « la base » n'est pas une classe accessible de « dérivé ».

11.2 $ / 5 États -

  

Si une classe de base est   accessible, on peut convertir implicitement   un pointeur vers une classe dérivée à une   pointeur sur cette classe de base (4.10,   4.11). [Note: Il en résulte que les membres et amis d'une boîte classe X   convertir implicitement un X * à un pointeur   à une société privée ou protégée immédiate   classe de base de X. Note -end]

Depuis Base n'est pas une classe accessible Derived quand on y accède en main, la conversion standard de classe dérivée à la classe de base est mal formé. D'où l'erreur.

EDIT 2:

Étudier les messages d'erreur de certains compilateurs populaires et qui devrait vous aider à obtenir une meilleure compréhension. Notez comment le mot « inaccessible » apparaît si souvent et de manière cohérente à travers tous les messages d'erreur

Les références proviennent du projet N3000 standard. Je suis encore télécharger la dernière version:)

  

GCC prog.cpp: En fonction « int   main () »: prog.cpp: 27: erreur: « base » est   une base inaccessible de « dérivée »

     

Comeau en ligne "ComeauTest.c", ligne 26:   Erreur: conversion de la base inaccessible   « Base » de classe n'est pas             permis         ptr = new dérivée;

     

VS2010 erreur C2243: 'type cast':   conversion de « dérivée * » à « base de   * » Existe, mais il est inaccessible

Autres conseils

Je soupçonne que le problème est que vous ne pouvez pas convertir un pointeur dérivé à un pointeur de base, comme l'héritage est privées.

Chusbad a fourni un je explication approfondie concernant la norme, essayez de fournir une explication accessible.

En C ++, il y a 3 niveaux d'accès: spécificateurs public, protected et private. Ceux-ci sont censées déterminer qui peut accéder aux méthodes, attributs ou classes de base. Il est typique parmi les langages orientés objet.

Ici, vous avez choisi l'héritage private. Conceptuellement, cela signifie que vous cherchez à cacher le fait héritant de Derived de Base à l'extérieur, ce qui signifie généralement ceci est un détail de mise en œuvre.

Par conséquent, la « extérieur » ne connaît pas cette relation. Ceci est renforcé par le compilateur avec ce message inaccessible.

D'un point de vue de la conception, l'héritage de private est généralement pas nécessaire. Soit le principe de substitution Liskov applique et que vous utilisez l'héritage public, soit il est un détail de mise en œuvre et que vous utilisez la composition.

Vous savez que class derived hérite de class base, mais la fonction main() ne le sait pas. La raison pour laquelle la fonction main() ne sait pas ce que vous avez fait class derived Hériter PRIVÉS de class base.

Par conséquent, lorsque vous essayez d'attribuer new derived à ptr, les types de pointeurs ne sont pas compatibles.

Essayez ceci:

#include<iostream>
#include<conio.h>
using namespace std;

class base
{
      private:
      public:
          virtual void sid() // You might want to declare sid virtual
             {
                  cout<<"base";
             } 
          virtual ~base() // You then probably need a virtual destructor as well.
             {
             } 
};

class derived : public base //public inheritance
{
      private:
      public:
             void sid()
             {
                  cout<<"derived";
             }
};

int main()
{
    base * ptr;
    ptr = new derived;
    ptr->sid();
    getch();
    return 0;
}

ce qui donne C2243 d'erreur: 'type cast': la conversion de 'dérivé *' à 'base *' existe, mais est inaccessible Cette classe dérivée a été héritée en privé .donc objet de classe de base n'est pas est créé lorsque la création derieved get arrive. pour créer l'objet derive premiers appels va créer l'objet de classe de base qui ne se produit pas. soltuion est d'obtenir la classe publique. il importe que votre doesn utilisant le mot clé virtuel avec des fonctions membres ou non.

Vous devez déclarer votre fonction sid () dans la classe de base comme virtuel. Une fonction virtuelle peut être remplacée par une classe dérivée. Dans le cas contraire, vous probablement une erreur de compilation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top