2010-08-08 10 views

Respuesta

23

Sí, una función miembro puede devolver un puntero (o referencia) a un miembro de datos privados. No hay nada mal con esto excepto que en la mayoría de los casos rompe la encapsulación.

El miembro de datos ciertamente se puede leer a través del puntero o referencia devuelto. Si se puede escribir o no, depende de si el puntero o la referencia devueltos corresponde a un objeto calificado para la const (es decir, si devuelve un const T*, no podrá modificar el apuntado a T). Por ejemplo:

class Example 
{ 
public: 
    int*  get()    { return &i; } 
    const int* get_const() const { return &i; } 
private: 
    int i; 
}; 

int main() 
{ 
    Example e; 

    int* p = e.get(); 
    int a = *p; // yes, we can read the data via the pointer 
    *p = 42;  // yes, we can modify the data via the pointer 

    const int* cp = e.get_const(); 
    int b = *cp; // yes, we can read the data via the pointer 
    *cp = 42;  // error: pointer is to a const int   
} 
+1

Ver el Artículo 28. Efectivo de C++ y +1. –

+0

este enfoque es peligroso. Se puede bloquear fácilmente int * x = Example() .get(); eliminar x; int * y = Ejemplo().obtener(); // Bloqueos –

+1

@jack london: IMO, en C++, si va a hacer una gestión manual de la memoria, simplemente no puede invocar 'delete' en punteros arbitrarios y esperar salirse con la suya. Si administra la memoria manualmente, debe saber lo que está haciendo. – UncleBens

3

Sí, se puede devolver y se puede leer y escribir en. No es más o menos peligroso que tomar la dirección de cualquier otra variable. Public/private/protected son construcciones sintácticas que se comprueban en tiempo de compilación, y no son "contagiosas" o parte del tipo de algo.

1

Un miembro privado no es diferente de un miembro público o de cualquier otro tipo de instancia. Entonces, sí, puedes tomarles indicadores y devolverlos.

Al tomar punteros a cualquier miembro basado en instancia, debe tener cuidado de que la clase principal no se elimine y no salga del ámbito, a menos que tome ese puntero y haga una copia verdadera de los datos/objetos apunta a. Si se elimina o queda fuera del alcance, el puntero se convierte en un puntero colgante, y ya no puede usarlo sin que su aplicación explote (o trabaje en objetos inexistentes, y haciendo que su programa haga cosas inesperadas, pero no estrellarse).

consideraciones de diseño:

La exposición de cualquiera de sus detalles de implementación interna es potencialmente una violación de encapsulación. Sin embargo, si solo desea encapsular cómo se crea/recupera el objeto que está devolviendo, entonces esta es una solución razonable. Esto le permitiría cambiar la clase para obtener el objeto miembro de otra forma (como consultar un archivo, o un diccionario interno) sin romper el código que llama a estos métodos.

1

"¿se bloqueará o hay algo altamente inseguro acerca de esto? ¿Pueden leerse o escribirse los datos apuntados?"

private/protected/public no tienen ningún efecto en runtime, por lo que no pueden influir en la ejecución del programa o incluso bloquear el programa. Se comprueban en en tiempo de compilación y hacen que su compilador genere un error al compilar si hay una violación.

0

El calificador const no lo protegerá en esos casos. Teniendo en cuenta la respuesta de James, intenta emitir el const int * a int *

int* cp = (int*)e.get_const(); 

Usted se todavía será capaz de modificar.

Cuestiones relacionadas