设为首页 加入收藏

TOP

9.3 继承机制下的访问控制
2013-10-07 12:40:01 来源: 作者: 【 】 浏览:73
Tags:9.3 继承 机制 访问 控制

9.3  继承机制下的访问控制

对在派生类中访问继承下来的成员这个问题需要更仔细地审视。考虑一下派生类中基类private成员的状态。

在上一个示例中,我们有很好的理由选择拥有public数据成员的CBox类版本,而非后来开发的、拥有private数据成员的更安全的版本。原因在于虽然基类的private数据成员也是派生类的成员,但它们在派生类中仍然是基类所私有的,因此添加到派生类的成员函数不能访问它们。只有通过不属于基类private部分的基类函数成员,才能在派生类中访问它们。我们可以非常简单地证实这一点,方法是将CBox类的所有数据成员修改为private,然后在派生类CCandyBox中添加一个Volume()函数,这样类定义将如下所示:

  1. // Version of the classes that will not compile  
  2. class CBox  
  3. {  
  4. public:  
  5. CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0):  
  6. m_Length(lv), m_Width(wv), m_Height(hv){}  
  7.  
  8. private:  
  9. double m_Length;  
  10. double m_Width;  
  11. double m_Height;  
  12. };  
  13.  
  14. class CCandyBox: public CBox  
  15. {  
  16. public:  
  17. char* m_Contents;  
  18.  
  19. // Function to calculate the volume of a CCandyBox object  
  20. double Volume() const           // Error - members not accessible  
  21. { return m_Length*m_Width*m_Height; }  
  22.  
  23. CCandyBox(char* str = "Candy") // Constructor  
  24. {  
  25. m_Contents = new char[ strlen(str) + 1 ];  
  26. strcpy_s(m_Contents, strlen(str) + 1, str);  
  27. }  
  28.  
  29. ~CCandyBox()    // Destructor  
  30. { delete[] m_Contents; }  
  31. }; 

使用这些类的程序不能编译。CCandyBox类中的Volume()函数企图访问基类的private成员,这是非法的。

试一试:访问基类的私有成员

但使用基类的Volume()函数是合法的,因此如果我们将Volume()函数的定义移到基类CBox的public部分,则不仅该程序能够编译,而且还可以使用该函数来获得CCandyBox对象的体积。新建一个WIN32项目Ex9_02,在Box.h文件中输入下面的内容:

  1. // Box.h in Ex9_02  
  2. #pragma once  
  3.  
  4. class CBox  
  5. {  
  6. public:  
  7. CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0):  
  8. m_Length(lv), m_Width(wv), m_Height(hv){}  
  9.  
  10. //Function to calculate the volume of a CBox object  
  11. double Volume() const  
  12. { return m_Length*m_Width*m_Height; }  
  13.  
  14. private:  
  15. double m_Length;  
  16. double m_Width;  
  17. double m_Height;  
  18. }; 

该项目中CandyBox.h头文件的内容如下:

  1. // Header file CandyBox.h in project Ex9_02  
  2. #pragma once  
  3. #include "Box.h"  
  4. class CCandyBox: public CBox  
  5. {  
  6. public:  
  7. char* m_Contents;  
  8.  
  9. CCandyBox(char* str = "Candy")          // Constructor  
  10. {  
  11. m_Contents = new char[ strlen(str) + 1 ];  
  12. strcpy_s(m_Contents, strlen(str) + 1, str);  
  13. }  
  14.  
  15. ~CCandyBox()                // Destructor  
  16. { delete[] m_Contents; };  
  17. }; 

本项目的Ex9_02.cpp文件包含以下内容:

  1. // Ex9_02.cpp  
  2. // Using a function inherited from a base class  
  3. #include <iostream>         // For stream I/O  
  4. #include <cstring> // For strlen() and strcpy()  
  5. #include "CandyBox.h" // For CBox and CCandyBox  
  6. using std::cout;  
  7. using std::endl;  
  8.  
  9. int main()  
  10. {  
  11. CBox myBox(4.0,3.0,2.0); // Create CBox object  
  12. CCandyBox myCandyBox;  
  13. CCandyBox myMintBox("Wafer Thin Mints");  
    // Create CCandyBox object  
  14.  
  15. cout << endl 
  16. << "myBox occupies " << sizeof myBox    // Show how much memory  
  17. << " bytes" << endl     // the objects require  
  18. << "myCandyBox occupies " << sizeof myCandyBox  
  19. << " bytes" << endl 
  20. << "myMintBox occupies " << sizeof myMintBox  
  21. << " bytes";  
  22. cout << endl 
  23. << "myMintBox volume is " << myMintBox.Volume();     
    // Get volume of a  
  24.                                                  
    // CCandyBox object  
  25. cout << endl;  
  26. return 0;  

该示例产生下面的输出:

  1. myBox occupies 24 bytes  
  2. myCandyBox occupies 32 bytes  
  3. myMintBox occupies 32 bytes  
  4. myMintBox volume is 1 

示例说明

增加的输出是最后一行,该行显示出现在属于基类public部分的Volume()函数产生的数值。在派生类内部,该函数在派生类中对基类继承的成员进行操作。Volume()函数完全是派生类的成员,因此可以自由地处理派生类的对象。

派生类对象的体积值是1,因为在创建CCandyBox对象时,为了创建该对象的基类部分而首先调用了默认构造函数CBox(),该函数将默认的CBox尺寸设定为1。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇9.5.2 对类友元关系的限制 下一篇9.6.2 使用指向类对象的指针

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: