假设一个类有私有数据成员,但是setter和getter在公共作用域中。如果你从这个类继承,你仍然可以调用那些setter和getter - 从而访问在基类中的私有数据成员。既然派生类不能继承私有数据成员,那么这是如何可能的呢?
假设一个类有私有数据成员,但是setter和getter在公共作用域中。如果你从这个类继承,你仍然可以调用那些setter和getter - 从而访问在基类中的私有数据成员。既然派生类不能继承私有数据成员,那么这是如何可能的呢?
派生类不会继承私有数据成员的访问权限。尽管如此,它会继承完整的父级对象,其中包含该类声明的任何私有成员。
size_t
成员的对象在32位和64位编译中可能具有不同的布局),你就会覆盖完全不同的数据。 - David Thornleythis
并相应地进行偏移来以一种狡猾且不可移植的方式操作私有数据。 - Emile Cormier这取决于继承类型。如果你私有继承,那么派生类就无法访问基类的私有成员。
Access public protected private
-----------------------------------------------------------
members of the same class yes yes yes
members of derived classes yes yes no
not members yes no no
因为getters和setters是公共的,它们可以被任何人调用,而不仅仅是派生类。
*.h
class Mamifere
{
private:
int a;
public:
Mamifere();
virtual ~Mamifere();
int getA();
// ~Mamifere(); //le delete dans le exp02() affiche seulement mamifere mort :( destructeur de la class mere
void manger() ;
virtual void avancer() const;
};
class Deufin:public Mamifere{
public:
Deufin();
void manger() const;
void avancer() const;
~Deufin();
};
*.cpp
Mamifere::Mamifere(){
printf("nouveau mamifere est nee\n");
this->a=6;
}
Mamifere::~Mamifere(){
printf("mamifere Mort :(\n");
}
void Mamifere::manger() {
printf("hhhh je mange maifere %d\n",Mamifere::getA());
}
void Mamifere::avancer() const{
printf("allez-y Mamifere\n");
}
Deufin::Deufin(){
printf("nouveau Deufin est nee\n");
}
int Mamifere::getA(){
return this->a;
}
void Deufin::manger() const{
printf("hhhh je mange poisson\n");
}
void Deufin::avancer() const{
printf("allez-y Deufin\n");
}
Deufin::~Deufin(){
printf("Deufin Mort :(\n");
}
main.cpp
void exp031(){
Mamifere f;//nouveau mamifere est nee // nouveau Deufin est nee
Deufin d;
f.avancer();//allez-y Deufin (resolution dynamique des lien la presence de mot cle virtual)
f.manger();//hhhh je mange maifere (resolution static des lien pas de mot cle virtual)
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(){
exp031();
getchar();
return 0;
}
使用模式
class MyClass {
private: int a;
public: void setA(int x) { a = x; }
public: int getA() const { return a; }
};
看起来是面向对象的,具有封装的特性。
然而正如你所注意到的,你仍然可以直接访问私有字段,并没有比将a
公开并直接访问它更好。
在C++中使用这样的getter和setter并没有太多意义。
a
的访问(假设计算a
需要很多工作),你可以只需将其制作成一个属性即可完成。但是,在C++中,你需要去替换所有引用MyClass.a
的代码为MyClass.GetA();
。 - Billy ONealGetters 和 Setters 并不能完全控制私有数据成员,控制权仍然在父类。