public protected private关键字
我们知道C++中的类,有三种访问权限(也称作访问控制),它们分别是public、protected、private。
关于这三个关键字理解了下面的框图
访问权限 | public | protected | private |
---|---|---|---|
对本类 | 可见 | 可见 | 可见 |
对子类 | 可见 | 可见 | 不可见 |
对外部(调用) | 可见 | 不可见 | 不可见 |
框图第一行看(对本类行),则代表着类内部三个关键字的权限。
如果框图一列列看,则代表继承角度来看三个关键字的权限。如public列代表对本类,对子类,对外部调用三种情况的权限,其它列相同。
代码验证上表框图权限关系
#include <iostream>
#include <string>
#include <string.h>
#include <thread>
using namespace std;
namespace zj001{
class Person{
public:
Person(const string& name, int age ):m_name(name), m_age(age){
}
void showPersonNameInfo() const {
cout << "Person name:" << m_name << endl; }
protected:
void showPersonAgeInfo() const {
cout << "Person age:" << m_age << endl; }
bool setPersonAge(int age) {
m_age = age; return true;}
int v_age;
private:
string m_name;
int m_age;
};
class Teacher: public Person {
public:
Teacher(const string name, int age, const string title):
Person(name, age), m_title(title){
}
void showTeacherTitleInfo() const {
cout << "Tech title: " << m_title << endl; }
bool setTeacherVirtualAge(int age) {
v_age = age; return true; } // Ok base protected call
protected:
void showTeacherAgeInfo() const {
showPersonAgeInfo(); } //Ok base protected call
//bool setTeacherAge(int age) { m_age = age; return true; } //error m_age base object private
bool setTeacherAgeInfo(int age) {
setPersonAge(age); return true; } //by Person public func set private m_age
private:
string m_title;
};
} /* end namespace zj001 */
namespace zj002{
class Person{
public:
Person(const string& name, int age ):m_name(name), m_age(age){
}
void showPersonNameInfo() const {
cout << "Person name:" << m_name << endl; }
protected:
void showPersonAgeInfo() const {
cout << "Person age:" << m_age << endl; }
bool setPersonAge(int age) {
m_age = age; return true;}
int v_age;
private:
string m_name;
int m_age;
};
class Teacher: protected Person {
public:
Teacher(const string name, int age, const string title):
Person(name, age), m_title(title){
}
void showTeacherTitleInfo() const {
cout << "Tech title: " << m_title << endl; }
bool setTeacherVirtualAge(int age) {
v_age = age; return true; } // ok call protected para
protected:
void showTeacherAgeInfo() const {
showPersonAgeInfo(); } //protected call
//bool setTeacherAge(int age) { m_age = age; return true; } //error m_age is private
bool setTeacherAgeInfo(int age) {
setPersonAge(age); return true; } //by Person func set private m_age
private:
string m_title;
};
} /* end namespace zj002*/
namespace zj003{
class Person{
public:
Person(const string& name, int age ):m_name(name), m_age(age){
}
void showPersonNameInfo() const {
cout << "Person name:" << m_name << endl; }
protected:
void showPersonAgeInfo() const {
cout << "Person age:" << m_age << endl; }
bool setPersonAge(int age) {
m_age = age; return true;}
int v_age;
private:
string m_name;
int m_age;
};
class Teacher: private Person {
public:
Teacher(const string name, int age, const string title):
Person(name, age), m_title(title){
}
void showTeacherTitleInfo() const {
cout << "Tech title: " << m_title << endl; }
bool setTeacherVirtualAge(int age) {
v_age = age; return true; } // ok call protected para
protected:
void showTeacherAgeInfo() const {
showPersonAgeInfo(); } //protected call
bool setTeacherAgeInfo(int age) {
setPersonAge(age); return true; } //by Person func set private m_age
bool setTeacherAge(int age) {
v_age = age; return true; } //error m_age is private
string v_title;
private:
string m_title;
};
} /* end namespace zj003*/
using namespace zj002;
int main(int argc, char** argv)
{
Teacher tc("zhangsan", 29, "jiaoshou");
/* using name space zj001 public
tc.showPersonNameInfo(); //OK public
tc.showPersonAgeInfo(); // erro is protected within this context
tc.m_age = 10; // is private within this context
*/
/* using name space zj002 protected
tc.showPersonNameInfo(); //erro base(protected) public -> protected
tc.showPersonAgeInfo(); // erro is protected within this context
tc.m_age = 10; // is private within this context
*/
/* using name space zj003 private
tc.showPersonNameInfo(); //erro zj003::Person' is not an accessible base(private) public -> private
tc.showPersonAgeInfo(); // erro is protected within this context
tc.m_age = 10; // is private within this context
*/
return 0;
}
三种权限也是一种集合概念,作用范围是 public > protected > private。在继承时,对派生类内部来说只有private权限与基类不同,遵循权限集合取小原则,对外部调用则完全遵循权限集合取小原则。
总结:
对于在没有继承情况下,在本身没有权限问题,都可以直接使用或访问方法。
在继承情况下会根据不同的继承情况,在派生类的从基类继承下来的东西才会有不同的权限。但其它总结下来也并不复杂。
- public方式继承下来的基类权限,在派生类中不变。相当于类内部权限问题。
- protected方式继承下来的基类权限,在派生类中都基类的public权限变为protected权限(其实在类内部权限没有变,只是在外部调用时才体现出权限的作用)。
- private方式继承来下的基类权限,在派生类中的基类权限都变为private权限(其实在类内部权限没有变,只是在外部调用时才体现出权限的作用)。