37.public,protected和private访问和继承权限的区别?
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
二、继承权限
- 派生类继承自基类的成员权限有四种状态:public、protected、private、不可见
- 派生类对基类成员的访问权限取决于两点:一、继承方式;二、基类成员在基类中的访问权限
- 派生类对基类成员的访问权限是取以上两点中的更小的访问范围(除了 private 的继承方式遇到 private 成员是不可见外)。例如:
- public 继承 + private 成员 => private
- private 继承 + protected 成员 => private
- private 继承 + private 成员 => 不可见
参考资料来源:
黑马程序员、阿秀