"protected versus private"注意事项

Caveats with "protected versus private"

本文关键字:注意事项 private versus protected      更新时间:2023-10-16

我知道私有和受保护的定义,以及它们的区别。然而,当我继续和他们一起测试每一个不同的场景时,我并没有得到一致/预期的行为。这段话让我很困惑(摘自《21天自学C++》:)

总共存在三个访问说明符:public、protected和私有的如果函数有您类的对象,它可以访问公共成员数据和功能。该成员依次起作用,可以访问所有私有数据成员及其自己类的函数以及所有受保护的数据成员和任何类的函数它们衍生。

更具体地说,我写了一个代码来查看(代码在问题语句下面):1-如果猫类的两个实例Frisky和Boots可以查看彼此的私有数据。所谓"see"ing,我的意思是拥有以另一只猫为参数的成员函数,并能够设置/获取其私有数据。索赔是他们应该的,我可以确认

2-与"see"ing的含义相同,猫"Frisky"中的成员函数是否可以将Mammal的一个实例作为自变量,比如"Human",并设置/获取其受保护的数据?我从上面的声明中理解,是的,它应该,但代码不会编译。它抱怨自己受到了保护。

如果我理解错了,那么上面这段话究竟是什么意思呢?感谢您的帮助!

using namespace std;
class Mammal
{
public:
int myNumFeet;
void setMyNumVertebras(int);
protected:
int myNumVertebras;
};

class Cat : public Mammal
{
public:
void tellHisAge(Cat);
void tellHisNumVertebras(Mammal);
void setMyAge(int);
private:
int myAge;
int myWeight;
};
int main()
{
Cat Frisky;
Frisky.setMyAge(3);
Frisky.setMyNumVertebras(23);
Cat Boots;
Boots.setMyAge(4);
Boots.setMyNumVertebras(23);
Mammal Human;
Human.setMyNumVertebras(33);
Frisky.tellHisAge(Boots);
Frisky.tellHisNumVertebras(Human);
return 0;
}
void Cat::tellHisAge(Cat Boots)
{
cout << Boots.myAge <<endl;
}
void Cat::setMyAge(int age)
{
myAge = age;
}
void Mammal::setMyNumVertebras(int num)
{
myNumVertebras = num;
}
void Cat::tellHisNumVertebras(Mammal Human)
{
cout<< myNumVertebras <<endl;
}

您看到的是继承的正确行为。对等体可以看到彼此的privateprotected成员,但不能看到父类的privateprotected成员。

我提供两个参考:

  • 我之前写的一个答案是,为什么一个类看不到它继承的类的私有成员
  • C++常见问题解答中关于继承的部分

Cat的实例可以看到Catprivateprotected成员,因为假设Cat中的逻辑完全理解该级别的类的约束,并将维护所有的类不变量。

Cat,尽管是Mammal,但不了解Mammal的实现,因此看不到其private成员。这个想法是Mammal已经封闭了它的实现,包括对从它继承的类

Cat还可以在Cat的另一个实例(或从Cat继承的东西)中看到它从Mammal继承的protected成员。也就是说,如果将Cat(或从Cat派生的东西)传递给Cat的一个成员函数,它可以看到它从Mammal继承的protected成员,以及Cat的私有成员。

但是,它无法看到随机Mammal的受保护成员。如果您只是将Mammal&Mammal*传递给Cat中的方法,那么Cat所知道的只是它们有一个共同的祖先Mammal。如果另一个类继承自Mammal,它可能会以Cat所不期望的方式使用Mammalprotected成员。因此,您无法从Cat中访问Mammal对象的protected成员。

受保护的成员是最令人讨厌的成员,因为它们代表了基类和派生类之间非常有限的接口,没有抽象。它们天生就很脆弱。请参阅我上面的第一个链接以获得更一般的解释。