• c++继承访问权限控制(public、protected、private)


    前言

            在本文中,您将学习在C ++中使用公共继承,受保护继承和私有继承。您将通过示例学习在何处以及如何使用它。您可以从具有不同访问指定的基类声明一个派生,即公共继承,受保护继承或私有继承。

    #include 
    using namespace std;
    
    class base
    {
    .... ... ....
    };
    
    class derived : access_specifier base
    {
    .... ... ....
    };

    注意:可以使用public,protected或private关键字代替上面代码中使用的access_specifier(访问说明符)术语。

    访问控制和继承

    派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。

    我们可以根据访问权限总结出不同的访问类型,如下所示:

    访问publicprotectedprivate
    同一个类yesyesyes
    派生类yesyesno
    外部的类yesnono

    一个派生类继承了所有的基类方法,但下列情况除外:

    • 基类的构造函数、析构函数和拷贝构造函数。

    • 基类的重载运算符。

    • 基类的友元函数。

    继承类型

    当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种类型。继承类型是通过上面讲解的访问修饰符 access-specifier 来指定的。

    我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则:

    • 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有保护成员来访问。

    (1)基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问。

    (2)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。

    (3)通过派生类的对象访问从基类继承的成员,只能访问public成员。
     

    示例:

    1. #include
    2. using namespace std;
    3. class CFather
    4. {
    5. public:
    6. int m_testA{0};
    7. protected:
    8. int m_testB{0};
    9. private:
    10. int m_testC{0};
    11. };
    12. class CSon: public CFather
    13. {
    14. void test()
    15. {
    16. m_testA = 1; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
    17. m_testB = 1; // 编译正确 :public 继承后,在内部可以访问protected成员
    18. m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
    19. }
    20. };
    21. int main()
    22. {
    23. CSon _test;
    24. _test.m_testA = 2; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
    25. _test.m_testB = 2; // 编译错误 :public 继承后,在外部无法访问protected成员
    26. _test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
    27. system("pause");
    28. return 0;
    29. }
    • 保护继承(protected): 当一个类派生自保护基类时,基类的公有保护成员将成为派生类的保护成员。

    (1)基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员`不可直接``访问。
    (2)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
    (3)通过派生类的对象不能直接访问从基类继承的任何成员。
     

    示例:

    1. #include
    2. using namespace std;
    3. class CFather
    4. {
    5. public:
    6. int m_testA{0};
    7. protected:
    8. int m_testB{0};
    9. private:
    10. int m_testC{0};
    11. };
    12. class CSon: protected CFather
    13. {
    14. void test()
    15. {
    16. m_testA = 1; // 编译正确 :protected 继承后,在内部可以访问public成员
    17. m_testB = 1; // 编译正确 :protected 继承后,在内部可以访问protected成员
    18. m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
    19. }
    20. };
    21. int main()
    22. {
    23. CSon _test;
    24. _test.m_testA = 2; // 编译错误 :protected 继承后,在外部无法访问public成员
    25. _test.m_testB = 2; // 编译错误 :protected 继承后,在外部无法访问protected成员
    26. _test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
    27. system("pause");
    28. return 0;
    29. }

    此时,可以这么理解为 派生类 通过 protected继承 基类 之后 ,基类 中的 public变成了protected,其他保持原样。 

    1. class CFather
    2. {
    3. protected:// proteced 继承之后public变成了 proteced
    4. int m_testA{0};
    5. protected:
    6. int m_testB{0};
    7. private:
    8. int m_testC{0};
    9. };
    • 私有继承(private):当一个类派生自私有基类时,基类的公有保护成员将成为派生类的私有成员。

    (1)基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可直接访问。
    (2)派生类中的成员函数可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员。
    (3)通过派生类的对象不能直接访问从基类继承的任何成员。
     

    示例:

    1. #include
    2. using namespace std;
    3. class CFather // 基类
    4. {
    5. public:
    6. int m_testA{ 0 }; // 相当于int m_testA = 0;
    7. protected:
    8. int m_testB{ 0 };
    9. private:
    10. int m_testC{ 0 };
    11. };
    12. class CSon : private CFather // 私有继承(private)
    13. {
    14. void test()
    15. {
    16. m_testA = 1; // 编译正确 :private 继承后,在内部可以访问基类public成员
    17. m_testB = 1; // 编译正确 :private 继承后,在内部可以访问基类protected成员
    18. m_testC = 1; // 编译错误 :无论哪种继承,都无法访问基类private成员
    19. }
    20. };
    21. int main()
    22. {
    23. CSon _test;
    24. _test.m_testA = 2; // 编译错误 :private 继承后,在外部无法访问基类public成员
    25. _test.m_testB = 2; // 编译错误 :private 继承后,在外部无法访问基类protected成员
    26. _test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问基类private成员
    27. return 0;
    28. }

            此时,可以这么理解为 派生类 通过 private继承 基类 之后 ,基类 中的 publicprotected变成了private,其他保持原样。 

    1. class CFather
    2. {
    3. private:// private 继承之后public变成了 private
    4. int m_testA{0};
    5. private:// private 继承之后protected变成了 private
    6. int m_testB{0};
    7. private:
    8. int m_testC{0};
    9. };

    三者区别
    public继承方式

    基类中所有 public 成员在派生类中为 public 属性;
    基类中所有 protected 成员在派生类中为 protected 属性;
    基类中所有 private 成员在派生类中不能使用。


    protected继承方式

    基类中的所有 public 成员在派生类中为 protected 属性;
    基类中的所有 protected 成员在派生类中为 protected 属性;
    基类中的所有 private 成员在派生类中不能使用。


    private继承方式

    基类中的所有 public 成员在派生类中均为 private 属性;
    基类中的所有 protected 成员在派生类中均为 private 属性;
    基类中的所有 private 成员在派生类中不能使用。

    多继承

    多继承即一个子类可以有多个父类,它继承了多个父类的特性。

    C++ 类可以从多个类继承成员,语法如下:

    class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
    {
    <派生类类体>
    };

    其中,访问修饰符继承方式是 public、protected 或 private 其中的一个,用来修饰每个基类,各个基类之间用逗号分隔,如上所示。现在让我们一起看看下面的示例:

    1. #include
    2. // 基类 Shape
    3. class Shape {
    4. public:
    5. void setWidth(int w) {
    6. width = w;
    7. }
    8. void setHight(int h) {
    9. height = h;
    10. }
    11. protected:
    12. int width;
    13. int height;
    14. };
    15. // 基类PaintCost
    16. class PaintCost {
    17. public:
    18. int getCost(int area) {
    19. return area * 70;
    20. }
    21. };
    22. // 派生类
    23. class Rectangle :public Shape, public PaintCost {
    24. public:
    25. int getArea() {
    26. return (width * height);
    27. }
    28. };
    29. int main() {
    30. Rectangle Rect;
    31. int area;
    32. Rect.setWidth(5);
    33. Rect.setHight(7);
    34. area = Rect.getArea();
    35. // 输出对象的面积
    36. std::cout << "总面积:" << Rect.getArea() << std:: endl;
    37. // 输出总花费
    38. std::cout << "总花费:¥" << Rect.getCost(area) << std::endl;
    39. return 0;
    40. }

    输出结果: 

    部分参考自:

    C++的三种继承方式详解_c++继承的三种方式_NueXini的博客-CSDN博客

  • 相关阅读:
    iOS开发Swift-5-自动布局AutoLayout-摇骰子App
    AcWing 4713:反转字符串
    Django的设计模式及模板层
    【Spring】Spring MVC
    DFS-组合的输出
    几个友好java代码编写习惯建议
    nodejs格式化输入
    Linux多线程
    15.编写自动化测试(下)
    Pytorch的grid_sample是如何实现对grid求导的?(源码解读)
  • 原文地址:https://blog.csdn.net/m0_48241022/article/details/133870459