C++中的访问限定符之protected

C++中的访问限定符之protected

Fish 类包含公有属性 isFreshWaterFish。派生类 Tuna 和 Carp 通过设置它来定制 Fish 的行为—在海水还是淡水中游动。

class Fish
{
public:
   bool isFreshWaterFish;

   void Swim()
   {
      if (isFreshWaterFish)
         cout << "Swims in lake" << endl;
      else
         cout << "Swims in sea" << endl;
   }
};

class Tuna: public Fish
{
public:
   Tuna()
   {
      isFreshWaterFish = false;
   }
};

class Carp: public Fish
{
public:
   Carp()
   {
      isFreshWaterFish = true;
   }
};

然而,程序存在一个严重的缺陷:如果您愿意, 可在 main( )中修改这个被声明为公有的标志,这为在 Fish 类外部操纵该标志打开了方便之门:

myDinner.isFreshWaterFish = true; // but Tuna isn't a fresh water fish!

显然,需要让基类的某些属性能在派生类中访问,但不能在继承层次结构外部访问。这意味着您希望 Fish 类的布尔标志 isFreshWaterFish 可在派生类 Tuna 和 Carp 中访问, 但不能在实例化 Tuna 和 Carp的 main( )中访问。为此,可使用关键字 protected。

要让派生类能够访问基类的某个属性,可使用访问限定符 protected,如程序所示:

#include 
using namespace std; 

class Fish
{
protected:
   bool isFreshWaterFish; // accessible only to derived classes

public:
  void Swim()
   {
      if (isFreshWaterFish)
         cout << "Swims in lake" << endl;
      else
         cout << "Swims in sea" << endl;
   }
};

class Tuna: public Fish
{
public:
   Tuna()
   {
      isFreshWaterFish = false; // set base class protected member
   }
};

class Carp: public Fish
{
public:
   Carp()
   {
      isFreshWaterFish = false;
   }
};

int main()
{
   Carp myLunch;
   Tuna myDinner;

   cout << "Getting my food to swim" << endl;

   cout << "Lunch: ";
   myLunch.Swim();

   cout << "Dinner: ";
   myDinner.Swim();

   // uncomment line below to see that protected members
   // are not accessible from outside the class heirarchy
   // myLunch.isFreshWaterFish = false;

   return 0;
}

输出:

About my food
Lunch: Swims in lake
Dinner: Swims in sea

分析:
虽然程序清单 10.2 的输出与程序清单 10.1 相同,但对 Fish 类做了大量重要的修改,如第 3~16 行所示。第一项也是最显而易见的修改是,布尔成员 Fish::isFreshWaterFish 现在是一个 protected 属性,因此不能在 main( )中访问,如第 51 行所示(如果取消对这行的注释,将导致编译错误)。但在派生类 Tuna 和 Carp 中,仍可访问这个 protected 属性,如第 23 和 32 行所示。这个小程序表明,通过使用关键字 protected,可对需要继承的基类属性进行保护,禁止在继承层次结构外部访问它。

这是面向对象编程的一个非常重要的方面,它与数据抽象和继承一起确保派生类可安全地继承基类的属性,同时禁止在继承层次结构外部对其进行修改。

该文章会更新,欢迎大家批评指正。

推荐一个零声学院的C++服务器开发课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容
点击立即学习:C/C++后台高级服务器课程

你可能感兴趣的:(C++编程基础,c++)