2012-01-01 17 views
7

Creo que soy consciente de ACCESIBILIDAD pero no estoy seguro si entiendo la visibilidad muy clara¿Visibilidad de miembros de la clase?

Por ejemplo:

class X 
{ 
    int x; 
}; 

Aquí, 'X' es ser vistos en clase y fuera pero accesible de clase. Si estoy en lo correcto, ¿alguien puede explicar el texto en esa respuesta sobre cómo no se controla la visibilidad, etc.?

(C++ 03/11.0) Cabe señalar que es el acceso a los miembros y las clases base que se controla, no su visibilidad. Los nombres de los miembros siguen siendo visibles, y las conversiones implícitas a las clases base aún se consideran , cuando esos miembros y clases base son inaccesibles. La interpretación de una construcción dada se establece sin tener en cuenta el control de acceso . Si la interpretación establecida hace uso de nombres de los miembros o clases base inaccesible, está mal formada la construcción .

+0

En su lugar, debe solicitar una aclaración en los comentarios de esa respuesta. –

+1

@ TomalakGeret'kal: Eliminaré la referencia a esa respuesta de mi pregunta. – user1086635

+1

Um .. eso es todo lo contrario de lo que sugerí es lo correcto. –

Respuesta

7

Tal vez este ejemplo ayuda:

class Bob 
{ 
private: 
    int foo(int, int); 
}; 

class David : Bob 
{ 
    void goo() { 
     int a = foo(1, 2); // #1 
    } 
}; 

class Dani : Bob 
{ 
    void foo(); 
    void goo() { 
     int a = foo(1, 2); // #2 
    } 
}; 

En la línea número 1, el nombre foo es visibles, pero la función que los nombres no es accesible (por su condición de privado a Bob) Este es un error de compilación, pero el compilador sabe que existe una función potencial Bob::foo que coincidiría, pero no es accesible.

En la línea número 2, el nombre foo sólo se refiere a Dani::foo, mientras Bob::foo es no visible (porque es oculta), y así simplemente no hay función de emparejamiento para la llamada foo(1, 2). Esto también es un error de compilación, pero esta vez el error es que no hay ninguna función de coincidencia para la llamada.

+1

¿Puedo saber qué confusión podría causar? – user1086635

+0

@ user1086635 no estoy seguro de lo que quiere decir aquí: los números de línea simplemente no coinciden con la descripción. La línea n. ° 1 es "Clase Bob", pero parece querer decir "int foo (int, int);" y la línea n. ° 2 es "{". La redacción necesita edición. – Serodis

+0

@Serodis: Las referencias son a las líneas marcadas con los comentarios '// # 1' etc. Este estilo de anotación es una práctica común aquí en SO, ya que los bloques fuente no tienen ninguna otra forma de numeración fácilmente visible. –

7

C++ tiene alguna característica esotérica sobre la visibilidad y accesibilidad de los nombres de miembros de la clase privada. Por definición, los miembros y amigos de la clase solo pueden acceder al nombre de un miembro privado de la clase. Sin embargo, la regla de visibilidad puede confundir a muchos. Se pueden resumir de la siguiente manera.

  1. El nombre de un miembro privado solo es accesible para otros miembros y amigos.
  2. Un miembro privado es visible para todo el código que ve la definición de la clase. Esto significa que sus tipos de parámetros deben declararse aunque nunca se necesiten en esta unidad de traducción ...
  3. La resolución de sobrecarga ocurre antes de la verificación de accesibilidad.

En C++ hoy ("C++ 03" y variantes anteriores), las nociones de la accesibilidad y la visibilidad son independiente. Los miembros de clases y espacios de nombres son visibles siempre que estén "en el alcance " y no existe un mecanismo para reducir esta visibilidad desde el punto de declaración. La accesibilidad es solamente un parámetro para miembros de la clase y es ortogonal a la noción de visibilidad.Esta última observación es frecuentemente sorprendente para los programadores novatos en C++. Vea esto PDF.

Considere el siguiente ejemplo.

#include < complex> 

class Calc 
{ 
    public: 
     double Twice(double d); 
    private: 
     int Twice(int i); 
     std::complex Twice(std::complex c); 
}; 

int main() 
{ 
    Calc c; 
    return c.Twice(21); // error, Twice is inaccessible 
}  

Cuando el compilador tiene que resolver la llamada a una función, que hace tres cosas principales, en orden:

  • Antes de hacer cualquier otra cosa, los compilador busca un alcance que tiene por lo al menos una entidad llamada Twice y hace una lista de candidatos. En este caso, la búsqueda de nombre se ve primero en el ámbito de Calc para ver si hay al menos una función llamada Dos veces en ; si no existe, las clases base y los espacios de nombres adjuntos se considerarán sucesivamente, una en un tiempo , hasta que se encuentre un ámbito que tenga al menos un candidato. Sin embargo, en este caso , el primer ámbito que ve el compilador ya tiene una entidad llamada Twice; de ​​hecho, tiene tres y para que el trío se convierta en el conjunto de candidatos. (Para obtener más información sobre el nombre de búsqueda en C++, la discusión acerca de cómo afecta la forma en que debe empaquetar sus clases y sus interfaces

  • A continuación, el compilador realiza la resolución de sobrecarga para recoger la única mejor partido de la lista de candidatos. En este caso, el argumento es 21, que es un int, y las sobrecargas disponibles toman un doble, un int, y un complejo. Claramente el parámetro int es la mejor coincidencia para el argumento int (es una coincidencia exacta y no se requieren conversiones ), por lo que se selecciona dos veces (int).

  • Finalmente, el compilador realiza la comprobación de accesibilidad para determinar si se puede llamar a la función seleccionada.

Nota que accesibilidad (definido por los modificadores en C++) y visibilidad son independientes. La visibilidad se basa en las reglas de scoping de C++. Un miembro de la clase puede ser visible y inaccesible al mismo tiempo.

Los miembros estáticos como un ejemplo son visibles a nivel mundial a través de la ejecución de la aplicación, pero accesible sólo en relación con el modificador que se les aplica.

1

Como nota: (. Oposición a una struct donde los miembros son públicos por defecto) cuando se declara una class, el alcance es privada por defecto

El miembro de la variable 'x' es sólo accesible por su clase y sus amigos Nadie más puede acceder directamente a 'x' (indirectamente, si tiene una función que le devuelve una referencia, que es una muy mala idea).

El texto que cita habla de la visibilidad del compilador, por lo que X::x existe, no importa qué. No va a desaparecer solo porque es privado.La visibilidad se usa para encontrar el miembro al que hace referencia y se devuelve el primero que coincide. En ese punto, el compilador verifica la accesibilidad, si es accesible, está todo bien. Si no es mal formado.

Tenga en cuenta que he mencionado amigos. Esa palabra clave hace que todos los miembros variables sean accesibles. Cuando el compilador trata con un amigo, ignora por completo todas las palabras clave protegidas y privadas.

En la mayoría de los casos, es un proceso muy fácil. Va en orden. Período.

Donde se vuelve más complicado es cuando comienzas a usar funciones virtuales: estas pueden hacerse públicas, protegidas y privadas y eso puede cambiar dependiendo de la declaración de clase ... (A deriva de B y hace una función virtual protegida público, generalmente no es una buena idea, pero C++ no impide que lo haga). Por supuesto, esto solo se aplica a las funciones, no a los miembros variables, por lo que ese es un tema diferente.

Cuestiones relacionadas