operator online c++ precedence pointer-to-member

online - una pregunta sobre la prioridad de los operadores de C++ "dirección de" y "resolución de alcance"



operator precedence java (3)

En el primer caso, está tomando la dirección de puntero a miembro B::b . Dado que dicho puntero NO es un miembro del padre de A sino un objeto separado, no puede acceder a él a través del mecanismo protegido.

En el SEGUNDO caso donde funciona, está solicitando la dirección de la instancia específica de b , calificándola con su clase base para que en el caso de herencia múltiple el compilador sepa a qué clase base se refiere. En este contexto, el atributo protegido es visible.

Tenga en cuenta que esto compila:

class B { protected: int b; }; class A : public B { public: void foo(){ &A::b; } // Note here &A:: instead of &B:: };

Como ejemplo agregado, no funciona por la misma razón que el siguiente código (con suerte, más familiar) no funciona:

class B { protected: int b; }; class A : public B { public: void foo(const B* b_obj) { b_obj->b; } };

Hola, tengo este código con un error del compilador (el error es de Microsoft Visual Studio 2008):

class B { protected: int b; }; class A : public B { public: void foo(){ &B::b; }// error C2248: ''B::b'' : cannot access protected member declared in class ''B'' };

Si bien este código está libre de errores:

class B { protected: int b; }; class A : public B { public: void foo(){ &(B::b); } };

Los dos fragmentos me parecen equivalentes según mi conocimiento de la precedencia de los operadores, porque :: tiene una precedencia más alta que & (vea, por ejemplo, la tabla 2 en la página 137 de "NORMAS COMUNES CONTRA EL VEHÍCULO AÉREO C ++ NORMAS DE CODIFICACIÓN PARA EL DESARROLLO DEL SISTEMA Y PROGRAMA DE DEMOSTRACIÓN " http://www2.research.att.com/~bs/JSF-AV-rules.pdf )

Pero son diferentes ... Creo que es algo relacionado con "puntero a miembro de datos" pero no sé cómo encaja con la precedencia de los operadores.

Alguna explicacion

Gracias Alessandro


Esto es sólo una suplementación.
§5.3.1 / 2 dice:

El resultado del operador unario y es un puntero a su operando. El operando será un lvalue o un id-calificado. En el primer caso, si el tipo de expresión es "T", el tipo del resultado es "puntero a T." ...
Para un id-calificado, ... Si el miembro es un miembro no estático de la clase C del tipo T, el tipo del resultado es "puntero al miembro de la clase C del tipo T."

De acuerdo con §5.1 / 7, B::b incluye en el caso de id-calificado, pero (B::b) no lo hace. Entonces, el compilador lo interpreta como un lvalue.


La diferencia entre las dos afirmaciones se vuelve más obvia cuando intenta devolver el valor:

int* foo() { return &(B::b);} // This is a pointer to an int int A::* foo() { return &B::b; } // This is a pointer to a member of type int

Lo que quieres hacer es acceder a través del objeto A:

int A::* foo() { return &A::b; } // This is a pointer to a member of type int

A partir de la A se le permite acceder.
Accediendo a él a través de B es como acceder desde el exterior y, por lo tanto, activa los especificadores de acceso.