una que programacion poo orientada objetos miembros metodos herencia ejemplo derivada codigo clases clase c++ protected access-control

c++ - que - No se puede acceder al miembro protegido de la clase base en la clase derivada



miembros de una clase en programacion orientada a objetos (4)

Tengo el siguiente código:

struct A { protected: A() {} A* a; }; struct B : A { protected: B() { b.a = &b; } A b; };

Extrañamente no se compila. El culpable es el ba = &b; asignación: tanto GCC como clang se quejan de que A() está protegido, lo que no debería ser un problema porque B hereda A. ¿En qué rincón oscuro de la norma me he metido?


El significado de protected es que el tipo derivado tendrá acceso a ese miembro desde su propia base y no desde cualquier objeto aleatorio * . En su caso, le importa intentar modificar el miembro de b que está fuera de su control (es decir, puede configurar this->a , pero no ba )

Hay un truco para que esto funcione si estás interesado, pero una mejor solución sería refactorizar el código y no depender de hacks. Por ejemplo, podría proporcionar un constructor en A que tome un A* como argumento (este constructor debería ser público) y luego inicializarlo en la lista de inicializadores de B :

A::A( A* p ) : a(p) {} B::B() : b(&b) {}

* protected otorga acceso al miembro base en cualquier instancia de su propio tipo o derivada de su propio tipo.


En realidad, hay dos problemas separados aquí

La primera es que la línea no solo hace una asignación, sino que intenta inicializar la clase base (que funciona bien) y el miembro b . Para crear el miembro b necesita construirlo, y como miembro necesita acceso public a un constructor, que no tiene.

Entonces, la asignación tampoco puede acceder al miembro no público de b porque, de nuevo, no es del tipo B sino del tipo A lugar.

Recuerde que protected significa que puede acceder a partes de A través de un objeto B (o secundario) únicamente .

En este caso, díganos su problema real y podemos intentar ayudarlo a resolverlo. Heredar y componer del mismo tipo es un olor a diseño.


Parece una gran limitación del lenguaje C ++. ¿Cómo resolverías un problema como este?

class Node { public: void Save(); protected: virtual void SaveState(int type) = 0; }; class BinaryNode : public Node { protected: Node *left; Node *right; virtual void SaveState(int type) override { left->SaveState(type); right->SaveState(type); } };

En este ejemplo, no quiero que el método SaveState visible fuera de la jerarquía de Node . Sólo el método Save debe ser public .


Todos los compiladores que probé se quejaron de varias cosas, y específicamente el constructor protegido sería un problema incluso si se eliminara la instrucción de asignación.

No puede acceder a los miembros protected de ninguna instancia de un tipo del que deriva. Este problema se aclara en los ejemplos de 11.4p1.

class B { protected: int i; static int j; }; class D1 : public B { }; class D2 : public B { void mem(B*, D1*); }; void D2::mem(B* pb, D1* p1) { pb->i = 1; // ill-formed p1->i = 2; // ill-formed // ... }