37.public,protected和private访问和继承权限的区别?

发布时间 2023-07-03 21:36:15作者: CodeMagicianT

37.public,protected和private访问和继承权限的区别?

  • public的变量和函数在类的内部外部都可以访问。
  • protected的变量和函数只能在类的内部和其派生类中访问。
  • private修饰的元素只能在类内访问

派生类可以继承基类中除了构造/析构、赋值运算符重载函数之外的成员,这些成员的访问属性在派生过程中也是可以调整的,三种派生方式的访问权限如下表所示:注意外部访问并不是真正的外部访问,而是在通过派生类的对象对基类成员的访问。

派生类对基类成员的访问形象有如下两种:

●内部访问:由派生类中新增的成员函数对从基类继承来的成员的访问

外部访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问

1.公有继承

1.父类的公有属性成员,到子类还是公有

2.父类的保护属性成员,到子类还是保护

3.父类的私有属性成员,到子类不能访问

#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; // 编译错误 :public 继承后,基类的私有权限,在派生类中不可见,无论哪种继承,在派生类中基类私有成员都不可见,都无法访问基类private成员
	}
};

int main()
{
	CSon _test;

	_test.m_testA = 2; // 编译正确 :
	_test.m_testB = 2; // 编译错误 :
	_test.m_testC = 2; // 编译错误 :

	system("pause");
	return 0;
}

2.保护继承

1.父类的公有属性成员,到子类是保护

2.父类的保护属性成员,到子类还是保护

3.父类的私有属性成员,到子类不能访问

#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成员,在外部无法访问基类public成员
		m_testB = 1; // 编译正确 :protected 继承后,基类的保护权限,在派生类中为保护权限,在内部可以访问基类protected成员,在外部无法访问基类public成员
		m_testC = 1; // 编译错误 :protected 继承后,基类的私有权限,在派生类中不可见,无论哪种继承,在派生类中基类私有成员都不可见,都无法访问基类private成员
	}
};

int main()
{
	CSon _test;
	
	_test.m_testA = 2; // 编译错误 :protected 继承后,基类的公有权限,在派生类中为保护权限,在内部可以访问基类public成员,在外部无法访问基类public成员
	_test.m_testB = 2; // 编译错误 :protected 继承后,基类的保护权限,在派生类中为保护权限,在内部可以访问基类protected成员,在外部无法访问基类public成员
	_test.m_testC = 2; // 编译错误 :protected 继承后,基类的私有权限,在派生类中不可见,无论哪种继承,在派生类中基类私有成员都不可见,都无法访问基类private成员
	
	system("pause");
	return 0;
}

3.私有继承

1.父类的公有属性成员,到子类还是私有

2.父类的保护属性成员,到子类还是私有

3.父类的私有属性成员,到子类不能访问

#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成员,在外部无法访问基类public成员
		m_testB = 1; // 编译正确 :private 继承后,基类的保护权限,在派生类中为私有权限,在内部可以访问基类protected成员,在外部无法访问基类protected成员
		m_testC = 1; // 编译错误 :private 继承后,基类的私有权限,在派生类中不可见,无论哪种继承,在派生类中基类私有成员都不可见,都无法访问基类private成员
	}
};

int main()
{
	CSon _test;
	
	_test.m_testA = 2; // 编译错误 :private 继承后,基类的公有权限,在派生类中为私有权限,在内部可以访问基类public成员,在外部无法访问基类public成员
	_test.m_testB = 2; // 编译正确 :private 继承后,基类的保护权限,在派生类中为私有权限,在内部可以访问基类protected成员,在外部无法访问基类protected成员
	_test.m_testC = 2; // 编译错误 :private 继承后,基类的私有权限,在派生类中不可见,无论哪种继承,在派生类中基类私有成员都不可见,都无法访问基类private成员
	
	system("pause");
	return 0;
}

总结

一、访问权限

访问权限 外部 派生类 内部
public
protected
private

public、protected、private 的访问权限范围关系:

public > protected > private

二、继承权限

  1. 派生类继承自基类的成员权限有四种状态:public、protected、private、不可见
  2. 派生类对基类成员的访问权限取决于两点:一、继承方式;二、基类成员在基类中的访问权限
  3. 派生类对基类成员的访问权限是取以上两点中的更小的访问范围(除了 private 的继承方式遇到 private 成员是不可见外)。例如:
  • public 继承 + private 成员 => private
  • private 继承 + protected 成员 => private
  • private 继承 + private 成员 => 不可见

参考资料来源:

黑马程序员、阿秀