Domanda

Ecco il mio codice -

#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;
}

Questo dà un errore di tempo di compilazione.

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

Dato che il compilatore cercherà di chiamare la classe di base sid() perché ottengo questo errore? Qualcuno può spiegare questo.

È stato utile?

Soluzione

$ 11.2 / 4 stati -

  

Una classe base B di N è accessibile a R, se

     
      
  • un membro pubblico inventata di B sarebbe un membro pubblico di N, o
  •   
  • R si verifica in un membro o un amico della classe N, e un pubblico inventato   membro del B sarebbe un privato o   membro protetto di N, o
  •   
  • R si verifica in un organo o amico di una classe P derivata da N, e un   membro pubblico inventato di B sarebbe un   membro privato o protetto di P, o
  •   
  • esiste una classe S tale che B è una classe base di S accessibile a R   e S è una classe base di N accessibili   a R ".
  •   

Qui 'B' è 'base', 'N' è 'derivato' e 'R' è principale.

  1. Si consideri il secondo proiettile 'R si verifica in un membro o un amico di una classe N, ...'. Questa clausola non si applica come 'R' (principale) non è né un membro né amico di 'N' (Derivato)

  2. Si consideri il terzo proiettile 'R si verifica in un membro o un amico di una classe P ....'. Questo Natale anche non si applica per gli stessi motivi di cui sopra

  3. Si consideri il quarto proiettile Ancora una volta questa clausola non si applica

Quindi possiamo concludere che 'Base' non è una classe accessibile di 'derivata'.

$ 11.2 / 5 stati -

  

Se una classe base è   accessibile, si può convertire implicitamente   un puntatore a una classe derivata a un   puntatore a tale classe base (4,10,   4.11). [Nota: ne consegue che i membri e gli amici di una classe X può   implicitamente convertire un X * a un puntatore   ad un privato o protetto immediato   classe base di X. -end nota]

Dato Base non è una classe accessibile di Derived quando vi si accede in main, la conversione standard dalla classe derivata alla classe base è mal formata. Quindi l'errore.

EDIT 2:

di studio i messaggi di errore di alcuni compilatori popolari e che dovrebbe aiutare a ottenere una migliore comprensione. Nota come la parola 'inaccessibile' si apre così frequentemente e costantemente in tutti i messaggi di errore

I riferimenti sono dalla N3000 progetto di norma. Devo ancora scaricare l'ultima bozza:)

  

GCC prog.cpp: In funzione ‘int   main ()’: prog.cpp: 27: errore:‘base’è   una base inaccessibile di ‘deriva’

     

Comeau Online "ComeauTest.c", linea 26:   errore: la conversione a base di inaccessibile   classe "base" non è             permesso         PTR = new derivati;

     

VS2010 errore C2243: 'cast di tipo':   conversione da 'deriva *' a 'base   *' Esiste, ma è inaccessibile

Altri suggerimenti

Ho il sospetto che il problema è che non è possibile convertire un puntatore derivato a un puntatore di base, come l'eredità è privato.

Chusbad fornito una spiegazione approfondita che coinvolge lo standard, cercherò di fornire una spiegazione accessibile.

In C ++, ci sono 3 prescrittori Livello di accesso: public, protected e private. Quelli sono destinati a determinare chi può accedere ai metodi, attributi o classi di base. E 'tipico tra linguaggi Object Oriented.

Qui, eletto eredità private. Concettualmente questo significa che si cercano di nascondere il fatto che eredita da Derived Base verso terzi, il che significa in genere questo è un dettagli di implementazione.

Di conseguenza, il "esterno" non è a conoscenza di questo rapporto. Questo viene applicata dal compilatore con questo messaggio inaccessible.

Da un punto di vista del design, private eredità non è generalmente richiesto. O il principio di sostituzione Liskov si applica e si utilizza l'ereditarietà public, o si tratta di un dettaglio di implementazione e si utilizza la composizione.

Lo sai che eredita da class derived class base, ma la funzione main() non lo sa. La ragione per cui la funzione main() non sa è che hai fatto class derived ereditare privatamente da class base.

Quindi, quando si tenta di assegnare ai new derived ptr, i tipi di puntatore non sono compatibili.

Prova questo:

#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;
}

questo dà l'errore C2243: 'cast di tipo': conversione da 'derivato *' a 'base *' esiste, ma non è accessibile Questa classe derivata è stato ereditato privatamente .so oggetto classe di base non viene creata quando la creazione get derieved accade. per creare l'oggetto derivano primi inviti va a creare l'oggetto classe base che non accada. soltuion è derivare la classe pubblicamente. esso doesnt importa se la vostra utilizzando parola chiave virtuale con funzioni membro o meno.

È necessario dichiarare la funzione sid () nella classe base come virtuale. Una funzione virtuale può essere sostituita da una classe derivata. In caso contrario, si sarebbe probabilmente ottenere un errore di compilazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top