Sería posible para una función pública devolver un puntero a una variable privada en la clase. Si es así/si no, ¿qué pasaría? ¿se estrellaría o hay algo altamente inseguro acerca de esto? ¿Pueden leerse o escribirse los datos apuntados? Gracias¿Se puede acceder a una variable privada a través de su dirección?
Respuesta
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
}
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.
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.
"¿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.
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.
- 1. No se puede acceder a la función variable global
- 2. Llamar a una función a través de su dirección en la memoria en c/C++
- 3. ¿Debería acceder a una variable dentro de la misma clase a través de una propiedad?
- 4. ¿Se puede acceder a IEnumerable a medida que se devuelve?
- 5. No se puede acceder a un mensaje de error correspondiente a su nombre de campo
- 6. Acceder a una variable estática global de otra clase
- 7. Fatal error: No se puede acceder a la propiedad vacía
- 8. Asegúrese de que solo se puede acceder a la página a través de SSL
- 9. ASP.net acceder a una variable página maestra a través de la página de contenido
- 10. ¿Es posible acceder a una variable de instancia a través de un método estático?
- 11. ¿Por qué aún se puede acceder a los métodos de ayuda privada en las vistas?
- 12. acceder a la memoria privada de un hilo en OpenMP
- 13. php: Llamar a clases estáticas a través de una variable
- 14. ¿Se puede agregar una condición a una declaración de variable?
- 15. Ruby no puede acceder a la variable fuera del método?
- 16. utilizar una cadena de acceder a una variable local por su nombre
- 17. ¿Alguien puede suplantar una dirección IP a cualquier número?
- 18. Java accediendo a propiedad privada a través de Reflection
- 19. Cómo acceder a su sitio web a través de LAN en ASP.NET
- 20. de Java: no se puede acceder a través de la reflexión anotaciones
- 21. ¿Puede un archivo de etiqueta JSP acceder a su llamada a PageContext de JSP?
- 22. No se puede acceder a tablas temporales desde una función
- 23. Obtener una dirección MAC remota a través de IPv6
- 24. dirección C de una dirección de una variable
- 25. ¿Por qué es más rápido acceder al DOM a través de una variable en caché?
- 26. Fallo de segmentación al acceder a una estructura-función estática a través de puntero devuelto
- 27. Cómo acceder a la API RESTful a través de PHP
- 28. FileSystemWatcher No se puede acceder a la unidad de red
- 29. ¿Por qué mi subclase no puede acceder a una variable protegida de su superclase, cuando está en un paquete diferente?
- 30. Acceder a una variable fuera de una instrucción 'if'
Ver el Artículo 28. Efectivo de C++ y +1. –
este enfoque es peligroso. Se puede bloquear fácilmente int * x = Example() .get(); eliminar x; int * y = Ejemplo().obtener(); // Bloqueos –
@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