por - metodos en c++
¿Por qué puedo acceder a variables privadas en el constructor de copias? (5)
El constructor de copias es una función miembro de la clase y, como tal, tiene acceso a los miembros de datos de la clase, incluso a aquellos declarados como ''privados''.
Aprendí que nunca puedo acceder a una variable privada, solo con una función get en la clase. Pero entonces, ¿por qué puedo acceder a él en el constructor de copias?
Ejemplo:
Field::Field(const Field& f)
{
pFirst = new T[f.capacity()];
pLast = pFirst + (f.pLast - f.pFirst);
pEnd = pFirst + (f.pEnd - f.pFirst);
std::copy(f.pFirst, f.pLast, pFirst);
}
Mi declaración:
private:
T *pFirst,*pLast,*pEnd;
En mi humilde opinión, las respuestas existentes hacen un mal trabajo explicando el "por qué" de esto, centrándose demasiado en reiterar qué comportamiento es válido. "los modificadores de acceso funcionan en el nivel de clase, y no en el nivel de objeto". - ¿si, pero por qué?
El concepto general aquí es que son los programadores los que diseñan, escriben y mantienen una clase a la que se espera que comprenda la encapsulación OO deseada y que esté facultada para coordinar su implementación. Entonces, si está escribiendo class X
, está codificando no solo cómo un objeto X x
individual puede ser usado por código con acceso a él, sino también cómo:
- las clases derivadas pueden interactuar con él (a través de funciones virtuales opcionalmente puras y / o acceso protegido), y
- distintos objetos
X
cooperan para proporcionar los comportamientos deseados a la vez que respetan las condiciones posteriores e invariantes de su diseño.
Tampoco es solo el constructor de copias: una gran cantidad de operaciones pueden involucrar dos o más instancias de tu clase: si estás comparando, agregando / multiplicando / dividiendo, copiando, construyendo, clonando, asignando, etc. a menudo es el caso o simplemente debe tener acceso a datos privados y / o protegidos en el otro objeto, o quiere que permita una implementación de funciones más simple, más rápida o generalmente mejor.
Específicamente, estas operaciones pueden querer aprovechar el acceso privilegiado para hacer cosas como:
- (Copiar constructores) use un miembro privado del objeto "rhs" (lado derecho) en una lista de inicializadores, de modo que una variable miembro sea copiada en lugar de predefinida (incluso legal) y luego asignada también (de nuevo, si es legal)
- compartir recursos - manejadores de archivos, segmentos de memoria compartida, archivos compartidos para referenciar datos, etc.
- tomar posesión de las cosas, por ejemplo,
auto_ptr<>
"mueve" la propiedad al objeto en construcción - copie el "caché" privado, la calibración o los miembros del estado necesarios para construir el nuevo objeto en un estado óptimo de uso sin tener que regenerarlos desde cero
- Copiar / acceder a la información de diagnóstico / rastreo guardada en el objeto que se está copiando y que no se puede acceder a través de las API públicas, pero que podría ser utilizada por algún objeto de excepción o registro posterior (por ejemplo, algo sobre la hora / circunstancias cuando la instancia "original" no construida fue construido)
- realice una copia más eficiente de algunos datos: por ejemplo, los objetos pueden tener, por ejemplo, un miembro
unordered_map
pero públicamente solo exponen los iteradoresbegin()
yend()
con acceso directo alsize()
puedereserve
capacidad para una copia más rápida; peor aún si solo exponenat()
einsert()
y de lo contrariothrow
... - copiar las referencias a los objetos principales / de coordinación / administración que podrían ser desconocidos o de solo escritura para el código del cliente
Los modificadores de acceso funcionan en el nivel de clase y no en el nivel de objeto .
Es decir, dos objetos de la misma clase pueden acceder a los datos privados de los demás.
Por qué:
Principalmente debido a la eficiencia. Sería una sobrecarga de tiempo de ejecución no despreciable comprobar si this == other
cada vez que accedes a other.x
que tendrías que hacer si los modificadores de acceso funcionaran a nivel de objeto.
También es semánticamente lógico si lo piensas en términos de alcance: "¿Qué parte importante del código debo tener en cuenta al modificar una variable privada?" - Debe tener en cuenta el código de toda la clase, y esto es ortogonal a los objetos que existen en tiempo de ejecución.
Y es increíblemente conveniente al escribir constructores de copia y operadores de asignación.
Para entender la respuesta, me gustaría recordarles algunos conceptos.
- No importa cuántos objetos cree, solo hay una copia de una función en memoria para esa clase. Significa que las funciones se crean solo una vez. Sin embargo, las variables están separadas para cada instancia de la clase.
-
this
puntero se pasa a cada función cuando se llama.
Ahora es debido a this
puntero, la función puede ubicar variables de esa instancia particular. no importa si es privado o público. se puede acceder dentro de esa función. Ahora si pasamos un puntero a otro objeto de la misma clase. utilizando este segundo puntero podremos acceder a miembros privados.
Espero que esto responda a su pregunta.
Puede acceder a miembros privados de una clase desde dentro de la clase, incluso los de otra instancia.