Pregunta

Aquí está mi código -

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

Esto da un error de tiempo de compilación.

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

Desde el compilador tratará de llamar a la clase base sid() ¿por qué recibo este error? Por favor alguien puede explicar esto.

¿Fue útil?

Solución

$ 11.2 / 4 estados -

  

Una clase base B de N es accesible en R, si

     
      
  • un miembro público inventado de B sería un miembro público de N, o
  •   
  • R se produce en un miembro o amigo de clase N, y un público inventado   miembro del B sería un privado o   miembro protegido de N, o
  •   
  • R se produce en un miembro o amigo de una clase P derivado de N, y una   miembro público inventado de B sería una   miembro privado o protegido de P, o
  •   
  • existe una clase S tal que B es una clase base de S accesible en R   y S es una clase base de N accesible   en R ".
  •   

Aquí 'B' es 'Base', 'N' es 'Derivado' y 'R' se principal.

  1. Considere el segundo de balas 'R se produce en un miembro o amigo de una clase N, ...'. Esta cláusula no se aplica como 'R' (principal) no es ni un miembro ni amigo de 'N' (Derivado)

  2. Considere el de bala tercera 'R se produce en un miembro o amigo de una clase P ....'. Esta Noel tampoco se aplica por las mismas razones que el anterior

  3. Considere el cuarto de bala Una vez más, esta cláusula no se aplica

Por lo tanto podemos concluir que 'base' no es una clase de acceso de 'derivado'.

$ 11.2 / 5 estados -

  

Si una clase base es   accesible, se puede convertir implícitamente   un puntero a una clase derivada a una   puntero a la clase base (4,10,   4.11). [Nota: Se deduce que los miembros y amigos de una clase X puede   convertir implícitamente una X * a un puntero   a una empresa privada o protegida inmediata   clase base de X. nota -end]

Desde Base no es una clase accesible de Derived cuando se accede en main, la conversión estándar de clase derivada de la clase Base está enfermo formado. Por lo tanto el error.

EDIT 2:

Estudio de los mensajes de error de algunos compiladores populares y que debería ayudar a obtener una mejor comprensión. Nota cómo la palabra 'inaccesible' aparece de manera frecuente y consistente a través de todos los mensajes de error

Las referencias son del N3000 proyecto de norma. Estoy todavía a descargar el último borrador:)

  

GCC prog.cpp: En función de ‘int   main ()’: prog.cpp: 27: error:‘base’es   una base inaccesible de ‘derivado’

     

Comeau línea "ComeauTest.c", línea 26:   error: conversión a la base inaccesible   clase "base" no es             permitido         ptr = new derivan;

     

VS2010 error C2243: 'tipo fundido':   conversión de 'deriva *' a 'de base   *' Existe, pero es inaccesible

Otros consejos

Sospecho que el problema es que no se puede convertir un puntero a un puntero derivada de base, ya que la herencia es privado.

Chusbad proporcionó una explicación en profundidad que implica la norma, voy a tratar de dar una explicación accesible.

En C ++, hay 3 especificadores de nivel de acceso: public, protected y private. Los que tienen el propósito de determinar quién puede acceder a los métodos, atributos o clases base. Es típico entre los lenguajes orientados a objetos.

A continuación, se eligió la herencia private. Conceptualmente significa esto que tratan de ocultar el hecho de que hereda Derived de Base a los extranjeros, que por lo general significa que este es un detalles de implementación.

Como consecuencia, el "exterior" no es consciente de esta relación. Esto se hace cumplir por el compilador con este mensaje inaccessible.

Desde el punto de vista del diseño, no se requiere generalmente la herencia private. O bien el principio de sustitución de liskov se aplica y se utiliza la herencia public, ya sea que es un detalle de implementación y uso de la composición.

Usted sabe que hereda class derived de class base, pero la función main() no lo sabe. La razón por la función main() no sabe que es lo que hizo class derived hereda de forma privada desde class base.

Por lo tanto, cuando se intenta asignar a new derived ptr, los tipos de puntero no son compatibles.

Prueba esto:

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

esto da C2243 error: 'tipo fundido': conversión de 'derivado *' a 'de base *' existe, pero es inaccesible Esta clase derivada ha sido heredada de forma privada .so objeto de la clase base no se consigue creada cuando la creación get derieved sucede. para crear las primeras llamadas a objetos derivan va a crear el objeto de clase base que no está sucediendo. soltuion es derivar la clase públicamente. que doesnit importa si su uso de la palabra clave virtual con funciones miembro o no.

Se necesita declarar su función sid () en la clase base como virtual. Una función virtual puede ser sustituido por una clase derivada. De lo contrario, es probable que obtener un error de compilación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top