2010-04-20 34 views
8

supongamos que una clase tiene miembros de datos privados pero los setters y getters están en ámbito público. Si hereda de esta clase, aún puede llamar a esos setters y getters, lo que permite el acceso a los miembros de datos privados en la clase base. Cómo es posible, ya que se menciona que una clase derivada no puede heredar miembros de datos privadosHeredando miembros privados en C++

+10

Una clase derivada * * no heredará los miembros de datos privados. –

+1

Lo que es aún más confuso es que puede anular las funciones virtuales privadas de la clase base. –

+0

@ Space_C0wb0y: Eso no es nada confuso. Se llama Patrón de método de plantilla (que desafortunadamente no tiene nada que ver con plantillas C++) –

Respuesta

19

Una clase derivada no hereda el acceso a los datos privados. Sin embargo, hereda un objeto principal completo, que contiene los miembros privados que esa clase declara.

+0

aún puede manipularlo usando la aritmética del puntero – shreyasva

+0

@ user265260: Probablemente, pero ¿por qué? Eso me parece un problema que solo espera que suceda. Los miembros son privados por una razón, y si puede jugar con sus valores puede estropear un objeto.Además, si el diseño cambia (y puede cambiar entre diferentes compilaciones, es probable que un objeto con un miembro 'size_t' tenga un diseño diferente con compilaciones de 32 bits y de 64 bits), está pisoteando datos completamente diferentes. –

+4

@ user265260: Eso podría funcionar en * su * plataforma, pero nunca ** se requiere ** para funcionar. Nunca. –

4

Como los getters y setters son public, pueden ser invocados por cualquiera, no solo por las clases derivadas.

+1

mi duda es cómo puede manipular los valores de los miembros de datos privados ya que claramente no puede heredarlos – shreyasva

+1

y esos getters y setters son miembros de la clase base, por lo que tienen acceso a los datos privados. – amertune

+1

@ user235230: "claramente no puedes heredarlos" Esto es INCORRECTO. –

0

Getters y setters no le dan control total sobre los miembros de datos privados. El control aún se encuentra con la clase base.

0

Utilizando el patrón

class MyClass { 
    private: int a; 
    public: void setA(int x) { a = x; } 
    public: int getA() const { return a; } 
}; 

parece orientado a Objetos y tiene el enviado de encapsulación.

Sin embargo Como habrá notado, todavía se puede acceder directamente al ámbito privado y no hay nada ganado más de sólo hacer a pública y para acceder a él directamente.

Usar getters y setters como este realmente no tiene sentido en C++.

+0

En realidad lo hacen. En C# (por ejemplo), si decidiste almacenar en caché el acceso a 'a' aquí (asumiendo que en realidad era mucho trabajo calcular' a'), podrías hacer una propiedad y estarías listo. Sin embargo, en C++ tendrías que ir y reemplazar todo el código que hace referencia a 'MyClass.a' con' MyClass.GetA(); ' –

+1

Esta pregunta está relacionada con C++ y no con C#. Y muchas personas piensan que es inteligente proporcionar getters genéricos y setters para tipos integrales, pero no lo es. – Danvil

+1

"Usar getters y setters como este realmente no tiene sentido en C++". Permitir el acceso sin restricciones a los miembros de los datos, excepto a través de una interfaz bien definida (por ejemplo, getters y setters) hace que rastrear los errores sea una pesadilla. Debe buscar en todos los lugares donde está establecido ese miembro para tratar de determinar por qué tiene un valor inesperado. Al restringir el acceso a los miembros de la clase a través de esa interfaz bien definida, la depuración es mucho más sencilla, ya que el rastro de la pila proporciona información útil. – andand

6

Depende del tipo de herencia. Si hereda en privado, entonces la clase derivada NO tiene acceso a los miembros privados de la Base.

Access      public  protected private 
----------------------------------------------------------- 
members of the same class  yes   yes  yes 
members of derived classes  yes   yes   no 
not members     yes   no   no 
+0

Creo que esta respuesta puede ser engañosa o al menos inexacta. @JRL por favor intente dejarlo más claro. – rineez

1

se puede acceder a ellos por el acceso conjunto a las incubadoras y captadores públicos y acceso a ellos de esa

*.h 
 

 

 
class Mamifere{ 
 
private: 
 
\t int a; 
 
public: 
 
\t Mamifere(); 
 
\t virtual ~Mamifere(); 
 
\t int getA(); 
 
\t // ~Mamifere(); //le delete dans le exp02() affiche seulement mamifere mort :(destructeur de la class mere 
 
\t void manger() ; 
 
\t virtual void avancer() const; 
 
}; 
 

 

 
class Deufin:public Mamifere{ 
 
public: 
 
\t Deufin(); 
 
\t void manger() const; 
 
\t void avancer() const; 
 
\t ~Deufin(); 
 
}; 
 

 

 

 

 
*.cpp 
 

 
Mamifere::Mamifere(){ 
 
\t \t printf("nouveau mamifere est nee\n"); 
 
\t \t this->a=6; 
 
\t } 
 

 
Mamifere::~Mamifere(){ 
 
\t \t printf("mamifere Mort :(\n"); 
 
\t } 
 
void Mamifere::manger() { 
 
\t printf("hhhh je mange maifere %d\n",Mamifere::getA()); 
 
\t } 
 
void Mamifere::avancer() const{ 
 
\t printf("allez-y Mamifere\n"); 
 
} 
 

 
Deufin::Deufin(){ 
 
\t printf("nouveau Deufin est nee\n"); 
 
} 
 
int Mamifere::getA(){ 
 
\t return this->a; 
 
} 
 
void Deufin::manger() const{ 
 
\t printf("hhhh je mange poisson\n"); 
 
\t 
 
} 
 
void Deufin::avancer() const{ 
 
\t 
 
\t printf("allez-y Deufin\n"); 
 
} 
 

 
Deufin::~Deufin(){ 
 
\t printf("Deufin Mort :(\n"); 
 
} 
 

 

 

 
main.cpp 
 

 

 

 

 

 
void exp031(){ 
 
\t Mamifere f;//nouveau mamifere est nee // nouveau Deufin est nee 
 
\t Deufin d; 
 
\t 
 
\t f.avancer();//allez-y Deufin (resolution dynamique des lien la presence de mot cle virtual) 
 
\t f.manger();//hhhh je mange maifere (resolution static des lien pas de mot cle virtual) 
 
\t printf("a=%d\n",d.getA());//Deufin Mort :( mamifere Mort :((resolution static des lien la presence de mot cle virtual) distructeur de class fille appel auromatiquement le destructeur de la class mere 
 

 

 
} 
 

 
int main(){ 
 
\t exp031(); 
 
\t 
 
\t getchar(); 
 
    return 0; 
 
}

Cuestiones relacionadas