C++的三种继承方式详解以及区别

2022/4/22 20:12:39

本文主要是介绍C++的三种继承方式详解以及区别,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 目录
    • C++的三种继承方式详解以及区别
      • 前言
      • 一、public继承
      • 二、protected继承
      • 三、private继承
      • 四、三者区别
      • 五、总结
      • 后话

    C++的三种继承方式详解以及区别


    前言

    我发现有时候概念性的东西,理解起来还是很难的,于是本文用简单的几个例子,来说明这三种不同的继承方式,他们之前的区别~


    一、public继承

    • 基类的publicprotected成员的访问属性在派生类中保持不变,但基类的private成员不可直接访问

    • 派生类中的成员函数可以直接访问基类中的publicprotected成员,但不能直接访问基类的private成员。

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

    #include<iostream>
    
    using namespace std;
    
    class CFather
    {
    public:
    	int m_testA{0};
    protected:
    	int m_testB{0};
    private:
    	int m_testC{0};
    };
    
    class CSon: public CFather
    {
    	void test()
    	{
    		m_testA = 1; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
    		m_testB = 1; // 编译正确 :public 继承后,在内部可以访问protected成员
    		m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
    	}
    };
    
    int main()
    {
    	CSon _test;
    	
    	_test.m_testA = 2; // 编译正确 :public 继承后,在内部或者外部都可以访问public成员
    	_test.m_testB = 2; // 编译错误 :public 继承后,在外部无法访问protected成员
    	_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
    	
    	system("pause");
    	return 0;
    }
    

    二、protected继承

    • 基类的publicprotected成员都以private身份出现在派生类中,但基类的private成员不可直接``访问。
    • 派生类中的成员函数可以直接访问基类中的publicprotected成员,但不能直接访问基类的private成员。
    • 通过派生类的对象不能直接访问从基类继承的任何成员。
    #include<iostream>
    
    using namespace std;
    
    class CFather
    {
    public:
    	int m_testA{0};
    protected:
    	int m_testB{0};
    private:
    	int m_testC{0};
    };
    
    class CSon: protected CFather
    {
    	void test()
    	{
    		m_testA = 1; // 编译正确 :protected 继承后,在内部可以访问public成员
    		m_testB = 1; // 编译正确 :protected 继承后,在内部可以访问protected成员
    		m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
    	}
    };
    
    int main()
    {
    	CSon _test;
    	
    	_test.m_testA = 2; // 编译错误 :protected 继承后,在外部无法访问public成员
    	_test.m_testB = 2; // 编译错误 :protected 继承后,在外部无法访问protected成员
    	_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
    	
    	system("pause");
    	return 0;
    }
    

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

    class CFather
    {
    protected:// proteced 继承之后public变成了 proteced
    	int m_testA{0};
    protected:
    	int m_testB{0};
    private:
    	int m_testC{0};
    };
    

    三、private继承

    • 基类的publicprotected成员都以private身份出现在派生类中,但基类的private成员不可直接访问
    • 派生类中的成员函数可以直接访问基类中的publicprotected成员,但不能直接访问基类的private成员。
    • 通过派生类的对象不能直接访问从基类继承的任何成员。
    #include<iostream>
    
    using namespace std;
    
    class CFather
    {
    public:
    	int m_testA{0};
    protected:
    	int m_testB{0};
    private:
    	int m_testC{0};
    };
    
    class CSon: private CFather
    {
    	void test()
    	{
    		m_testA = 1; // 编译正确 :private 继承后,在内部可以访问public成员
    		m_testB = 1; // 编译正确 :private 继承后,在内部可以访问protected成员
    		m_testC = 1; // 编译错误 :无论哪种继承,都无法访问private成员
    	}
    };
    
    int main()
    {
    	CSon _test;
    	
    	_test.m_testA = 2; // 编译错误 :private 继承后,在外部无法访问public成员
    	_test.m_testB = 2; // 编译错误 :private 继承后,在外部无法访问protected成员
    	_test.m_testC = 2; // 编译错误 :无论哪种继承,都无法访问private成员
    	
    	system("pause");
    	return 0;
    }
    

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

    class CFather
    {
    private:// private 继承之后public变成了 private
    	int m_testA{0};
    private:// private 继承之后protected变成了 private
    	int m_testB{0};
    private:
    	int m_testC{0};
    };
    

    四、三者区别

    • public继承方式

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

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

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

    下表汇总了不同继承方式对不同属性的成员的影响结果

    继承方式/基类成员 public成员 protected成员 private成员
    public继承 public protected 不可见
    protected继承 protected protected 不可见
    private继承 private private 不可见

    五、总结

    1.不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。

    2.如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些不希望在派生类中使用的成员才声明为 private。

    3.如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。

    4.基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如,当继承方式为 protected 时,那么基类成员在派生类中的访问权限最高也为 protected,高于 protected 的会降级为 protected,但低于 protected 不会升级。再如,当继承方式为 public 时,那么基类成员在派生类中的访问权限将保持不变。


    后话

    我们这里说的是基类的 private 成员不能在派生类中使用,并没有说基类的 private 成员不能被继承。实际上,基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了。private 成员的这种特性,能够很好的对派生类隐藏基类的实现,以体现面向对象的封装性。由于 private 和 protected 继承方式会改变基类成员在派生类中的访问权限,导致继承关系复杂,所以实际开发中我们一般使用 public。



    这篇关于C++的三种继承方式详解以及区别的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


    扫一扫关注最新编程教程