2010-04-19 12 views
6

Supongamos que tiene una clase que define métodos virtuales con el especificador de acceso público. ¿Se puede cambiar el especificador de acceso en sus métodos modificados? Supongo que no. Buscando una explicación.Especificador de acceso al anular métodos

Respuesta

1

definitivamente se puede. Pero no tiene sentido. Si es una herencia pública, entonces siempre puedes lanzar un objeto a su base. Si se trata de una herencia privada, todos los métodos básicos ya son privados por defecto. En el caso de la herencia protegida, puede hacer que el método base sea privado, por lo que evita que las posibles clases derivadas lo llamen, pero realmente no entiendo por qué uno podría necesitarlo.

0

Sí, puede, y de hecho ni siquiera necesita anular o usar nada virtual.

class ABC { 
public: // or this may be protected, no difference 
    void woof(); 
    void moo(); 
}; 

class D : private ABC { // now woof and moo are private 
public: 
    using ABC::woof; // using declaration to make woof public again 
    ABC::moo; // access declaration (deprecated) does the same 
}; 

Lo mismo funciona si son virtuales, también. O, como señalaron otros, la búsqueda de funciones virtuales ignora el acceso especificado por la clase implementadora; cualquier clase a la que pueda enviarle puede proporcionar acceso en tiempo de compilación.

Por otro lado, sin las declaraciones especiales en D, la interfaz de publicABC de hecho sería inaccesible a través D porque no sería capaz de upcast a ABC. Y si woof y moo fueron virtual, le conviene hacer las anulaciones private para ocultarlas. Tal vez eso mejor responde la pregunta.

+1

Estoy bastante seguro de que hace una gran diferencia si fueran 'privados' en' clase ABC'. 'clase D' tiene que tener acceso a los miembros base antes de que pueda nombrarlos con éxito en una declaración' using'. OTOH, podrían haber sido 'protegidos' en' ABC' y el uso seguiría funcionando. –

+0

@Ben: lo siento, quise decir protegido. Fijo. – Potatoswatter

5

La respuesta es: tipo de. Solo puede cambiar el acceso de los miembros a los que tiene acceso la clase derivada. El tipo de herencia no tiene efecto: esto solo controla el acceso predeterminado para los miembros heredados (hasta cierto punto, siguiendo otras reglas).

Por lo tanto, puede hacer que los miembros protegidos de una clase base sean públicos o privados; o los miembros públicos de una base protegidos o privados. Sin embargo, no puede hacer que los miembros privados de una base sean públicos o protegidos.

Ejemplo:

class Foo 
{ 
protected: 
     void protected_member(); 

private: 
     void private_member(); 

public: 
     void public_member(); 
}; 

class Bar : private Foo 
{ 
public: 
     using Foo::protected_member; 
     using Foo::private_member; 
     using Foo::public_member; 
}; 

int main(int, const char**) 
{ 
     Bar bar; 

     return 0; 
} 

El código anterior provoca el siguiente error en g ++ 4.1.2:

MAIN.C: 7: error: 'vacío Foo :: private_member()' es privado

mAIN.C: 14: error: dentro de este contexto

Además, primordial no tiene nada que ver con cambiar el acceso de un método. Puede anular un método privado virtual, simplemente no puede llamarlo desde una clase derivada.

Cuestiones relacionadas