2010-11-25 11 views
12

tengo código como este:es un espacio de nombres necesario cuando se hace referencia a la clase base

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? 
}; 

qué necesito el espacio de nombres calificador, donde Derivado se refiere a que es la 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++?

+1

¿Qué compilador se queja si eso no es un secreto? –

Respuesta

11

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

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, la clase de base (y la propia clase) pueden ser referidos a dentro de la definición de clase sin cualificación o plantilla argumentos.

Citas de la norma:

9.2: Una clase-nombre se inserta en el ámbito en el que se declara inmediatamente después se ve el nombre de la clase. El nombre de clase también es insertado en el alcance de la clase en sí; esto se conoce como nombre-clase-inyectado. Para fines de verificación de acceso, el nombre de 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 accesible al público de la clase, y por lo tanto está disponible en las clases derivadas. Lo que demuestra mi punto sobre B estar bien junto con N :: B porque el nombre de B se hereda

Por cierto, esto también explica por qué el siguiente 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 acerca de los nombres de clase inyectados en plantillas. Es demasiado largo para pegar aquí. Hth

+0

Entonces, ¿por qué se queja el compilador? – Raveline

+0

@Raveline: Porque olvidé el {} :) Editado –

+0

Por lo que puedo ver, 9.2/2 solo dice que el nombre de clase "Derivado" se inyecta en Derivado. No dice nada sobre las clases base –

Cuestiones relacionadas