polinomio para metodo llamar derivar derivadas como codigo clases algoritmo c++ oop

c++ - para - ¿Por qué no puede funcionar un miembro protegido de llamada derivada en este código?



codigo en c para derivar un polinomio (4)

#include <iostream> class Base { protected: void somethingProtected() { std::cout << "lala" << std::endl; } }; class Derived : public Base { public: void somethingDerived() { Base b; b.somethingProtected(); // This does not compile somethingProtected(); // But this is fine } }; int main() { Derived d; d.somethingDerived(); return 0; }

Pensé que tal vez solo los miembros protegidos de this pueden ser utilizados y los miembros protegidos de otras instancias son inalcanzables.

Pero:

class Derived : public Base { public: void somethingDerived(Derived& d) { d.somethingProtected(); // This compiles even though d is // potentially a different instance } void somethingDerived(Base& b) { b.somethingProtected(); // This does not } };

Me siento un poco mareado por esto, ya que he estado programando en C ++ durante un tiempo, pero no pude encontrar ninguna explicación para este comportamiento.

EDITAR:

No importa si es la misma o una instancia diferente:

int main() { Derived d1, d2; // Two different instances d1.somethingDerived(d2); // This compiles fine d1.somethingDerived(d1); // This compiles fine return 0; }

EDIT2:

Parece que cuando se trata de derechos de acceso, no importa en absoluto qué instancia de una clase se está utilizando:

class Base { public: void something(Base& b) // Another instance { ++b.a; // But can enter private members } private: int a; };


Aunque el control de acceso en C ++ funciona en base a clases (en lugar de hacerlo por instancia), el especificador de acceso protected tiene algunas peculiaridades.

La especificación del lenguaje quiere garantizar que está accediendo a un miembro protegido de algún subobjeto base que pertenece a la clase derivada. Se supone que no puede acceder a los miembros protegidos de algunos objetos independientes no relacionados de tipo base. En particular, no puede acceder a miembros protegidos de objetos independientes de tipo base. Solo se le permite acceder a miembros protegidos de objetos base que están incrustados en objetos derivados como subobjetos base.

Por este motivo, debe acceder a los miembros protegidos a través de la sintaxis pointer->member syntax, reference.member o object.member , donde el puntero / referencia / objeto se refiere a la clase derivada .

Esto significa que en su ejemplo, el miembro protegido somethingProtected() no es accesible a través Base objetos Base , punteros Base * o Base & referencias, pero se puede acceder a través de objetos Derived * , punteros Derived * y Derived & referencias. Su acceso simple somethingProtected() protegido somethingProtected() está permitido, ya que es solo una abreviatura de this->somethingProtected() donde this es de tipo Derived * .

b.somethingProtected() infringe los requisitos anteriores.

Tenga en cuenta que de acuerdo con las reglas anteriores en

void Derived::somethingDerived() { Base *b = this; b->somethingProtected(); // ERROR this->somethingProtected(); // OK }

la primera llamada también fallará mientras que la segunda compilará, aunque ambas intenten acceder a la misma entidad.


Creo que tienes cierta confusión sobre cómo acceder a los miembros de la clase base. Es solo así:

class Derived : public Base void drivedMethod() { Base::baseMethod(); }

en su ejemplo, intenta acceder a un miembro protegido de otra instancia.

una instancia Derivada tendrá acceso a sus propios miembros protegidos, pero no a otros miembros protegidos de instancia de clase, esto es por diseño.

De hecho, el acceso a los miembros protegidos de otra clase, desde otros miembros de la instancia o desde la función principal, de hecho ambos están bajo acceso público ...

http://www.cplusplus.com/doc/tutorial/inheritance/ (busque la tabla de especificaciones de acceso para ver los diferentes niveles)

Ambos ejemplos demuestran lo mismo, por ejemplo:

void somethingDerived(Base& b) { b.somethingProtected(); // This does not

aquí su clase derivada obtiene b como parámetro, por lo tanto, está obteniendo otra instancia de base, y como b.somethingProtected no es público, no cumplirá.

esto cumplirá:

void somethingDerived() { Base::somethingDerived();

su segundo ejemplo cumple bien porque está accediendo a un método público en otra clase d

> void somethingDerived(Base& b) > { > b.somethingProtected(); // This does not > }


La clase Derived solo puede acceder al miembro base protegido en objetos Derived . No puede acceder al miembro en objetos que no son (necesariamente) Objetos Derived . En los casos que fallan, está tratando de acceder al miembro a través de una Base & , y dado que esto podría referirse a un objeto que no es Derived , no se puede realizar el acceso.


Lo que has hecho es ilegal en C ++. Un objeto protegido no puede acceder a un miembro protegido. Solo las funciones miembro pueden acceder a miembros protegidos. protected miembros protected se comportan igual que los miembros privados, excepto cuando son heredados por una clase derivada. Considere el programa que se proporciona a continuación para comprender la diferencia entre los miembros privados, públicos y protegidos.

class Base { private: void somethingPrivate() { std::cout << "sasa" << std::endl; } public: void somethingPublic() { std::cout << "haha" << std::endl; } protected: void somethingProtected() { std::cout << "lala" << std::endl; } }; class Derived : public Base { public: void somethingDerived() { Base b; b.somethingPublic(); // Works fine. somethingProtected(); // This is also fine because accessed by member function. //b.somethingProtected(); // Error. Called using object b. //somethingPrivate(); // Error. The function is not inherited by Derived. } };