2010-04-22 25 views
16

HI,Pregunta sobre C++ clase interna

En C++ clase interna,

class A { 
    public: 
     void f1(); 
    private: 
     void f2(); 
    class B { 
     private void f3(); 
    }; 

} 

¿Tiene una clase interna (B) tiene un puntero a su clase padre (A)? (como lo hace en Java). Y puede B llama a su clase padre método público/privado (como lo hace en Java).

Gracias.

Respuesta

28

No - en C++, las clases de anidamiento solo afectan los nombres y la visibilidad, no la semántica de la clase en sí. En lo que respecta al código generado, la clase anidada no es diferente de una que no está anidada.

Todo lo que ha cambiado es la visibilidad y el nombre (por ejemplo, si está en una sección private: de la clase externa, que no es visible para el mundo exterior, y si es en una sección public:, es visible, pero (por supuesto) para nombrarlo usa outer_class::inner_class. Sin embargo, es una clase completamente separada, por ejemplo, puede crear una instancia de la clase interna sin crear ninguna instancia de la clase externa.

Editar: Lo siento, me perdí parte de su pregunta. En C++ 0x, la clase interna tiene acceso a las partes privadas de la clase externa, en esencia, es como si la clase externa hubiera declarado a la clase interna como su amigo, por lo que los nombres privados son visibles, pero usted Todavía necesita pasar algo como una referencia a un objeto de la clase externa antes de que pueda invocar funciones miembro no estáticas de la clase externa.

Aunque no se supone que este sea el caso todavía, creo que la mayoría de los compiladores ya implementan esta parte en particular.

+4

Parece que esto está cambiando en C++ 0x. C++ 03 dice: "Los miembros de una clase anidada no tienen acceso especial a los miembros de una clase adjunta". C++ 0x FCD dice: "Una clase anidada es miembro y, como tal, tiene los mismos derechos de acceso que cualquier otro miembro". (ambos §11.8/1). (El cambio fue introducido por los defectos 45 y 494 del CWG: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45 y http://www.open-std.org/ jtc1/sc22/wg21/docs/cwg_defects.html # 494) –

+0

Bueno, eso elimina el impulso de escribir 'friend class {', que es compatible con algunos compiladores, pero no obviamente hace que la clase anidada no sea miembro en absoluto. – Potatoswatter

+1

@Potato: Curiosamente, incluso Comeau en el estricto modo C++ 03 no sigue el lenguaje C++ 03. Esto me lleva a creer que (a) es probable que por alguna razón sea imposible seguir el lenguaje C++ 03 (aunque todavía no he descubierto por qué, exactamente, además de lo que se menciona en los DR vinculados anteriormente), y (b) es probable que nadie realmente siga el lenguaje C++ 03 :-). –

7

No, la clase B no tiene un puntero a clase A, a menos que lo agregue explícitamente.

0

¿Tiene un puntero a la matriz: Nº
¿Tiene acceso a los padres miembros privados: Una especie de

creo que el si tiene acceso no está bien definido en la norma que podría ser incorrecto.
Pero se puede acceder a él en g ++

#include <iostream> 

class X 
{ 
    class Y 
    { 
     public: 
      Y(X* p) 
       :parent(p) 
      {} 
      void TryY() 
      { 
       // Access a private member of X 
       ++(parent->value); 
      } 

     private: 
      X* parent; 
    }; 

    public: 
     X() 
      :y(this) 
     { 
      value = 4; 
     } 

     void TryY() 
     { 
      y.TryY(); 
      std::cout << value << std::endl; 
     } 
    private: 
     Y y; 
     int value; 

}; 

int main() 
{ 
    X x; 
    x.TryY(); 
} 
+0

Debe ser un comportamiento incorrecto para C++ 03 según * §11.8/1 *. –