una que programacion orientada objetos miembros herencia ejemplos derivada codigo clases clase c++ namespaces language-lawyer

c++ - que - Se requiere un espacio de nombres para referirse a la clase base



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

Tengo un código como este:

namespace N { class B { public: virtual void doStuff(B *) = 0; }; } // not in a namespace class Derived : public N::B { public: void doStuff(B *); // Should this be N::B, or is B ok? };

¿Necesito el calificador del espacio de nombres donde Derived se refiere a su clase base? GCC y MSVC están contentos con el código tal como está escrito, pero otro compilador se queja a menos que coloque el espacio de nombres. ¿Qué dice el estándar de C ++?


Dentro de la definición de clase B está bien. Ese es el llamado nombre de clase inyectado .

Esto también se refiere a las plantillas (sin contar las bases dependientes). P.ej

template <class T> class B{}; template <class T> class C: public B<int> { void f(B* p) {} //same as B<int>* p void f(C* p) {} //same as C<T>* p };

En general, se puede hacer referencia a la clase base (y a la clase misma) dentro de la definición de clase sin calificación o argumentos de plantilla.

Citas del estándar:

9.2: Un nombre de clase se inserta en el ámbito en el que se declara inmediatamente después de que se vea el nombre de clase. El nombre de clase también se inserta en el alcance de la clase en sí; esto se conoce como el nombre de clase inyectado. A los efectos de la verificación de acceso, el nombre de la clase inyectada se trata como si fuera un nombre de miembro público.

De esta definición se deduce que el nombre de la clase en sí es públicamente accesible desde la clase y, por lo tanto, está disponible en las clases derivadas. Lo que prueba mi punto acerca de que B está bien junto con N :: B porque el nombre B es heredado

Por cierto, esto también explica por qué lo siguiente no es válido:

template <class T> class B{}; template <class T> class C: public B<T> { voiid f(B* p){} //ERROR // the above is invalid!! Base class is dependent therefore //its scope is not considered during unqualified name lookup void g(typename C::B* p){} //this is valid, same as B<T>* p };

14.6.1 Habla sobre nombres de clase inyectados en plantillas. Es demasiado largo para pegar aquí. Hth