欢迎使用Markdown编辑器写博客
一:成员的访问权限
1: public访问权限
一个类的public成员变量、成员函数,可以通过类的成员函数、类的实例变量进行访问
<实际上,类的成员函数,可以访问本类内的任何成员变量和成员函数>
- #include<iostream>
- #include<string>
- using namespace std;
- class AccessTest
- {
- public:
- int pub_mem;
- int pub_fun(){};
- protected:
- int prot_mem;
- int prot_fun(){};
- private:
- int priv_memb;
- int priv_fun(){};
- };
- int main()
- {
- AccessTest at;
- at.pub_mem; //OK, 类变量可以访问public成员
- at.pub_func(); //OK, 访问public成员函数是没有问题的
- return 0;
- }
#include<iostream>
#include<string> using namespace std; class AccessTest { public: int pub_mem; int pub_fun(){}; protected: int prot_mem; int prot_fun(){}; private: int priv_memb; int priv_fun(){}; }; int main() { AccessTest at; at.pub_mem; //OK, 类变量可以访问public成员 at.pub_func(); //OK, 访问public成员函数是没有问题的 return 0; }
2:protected访问权限
一个类的protected成员变量、成员函数,无法通过类的实例变量进行访问。但是可以通过类的友元函数、友元类进行访问。
- #include<string>
- #include<iostream>
- using namespace std;
- class AccessTest
- {
- friend void Atest();
- friend class CAtest;
- public:
- int pub_mem;
- void pub_fun(){}
- protected:
- int prot_mem;
- void prot_fun(){}
- private:
- int priv_memb;
- void priv_fun(){}
- };
- class CAtest
- {
- public:
- void x()
- {
- AccessTest t;
- t.prot_fun(); //OK,友元类可以访问protected成员函数
- int x=t.prot_mem; //OK,友元类可以访问protected成员变量
- }
- };
- void Atest()
- {
- AccessTest t;
- t.prot_fun(); //OK,友元函数可以访问protected成员函数
- int x=t.prot_mem; //OK,友元函数可以访问protected成员变量
- }
- int main()
- {
- AccessTest at;
- at.prot_mem; //ERROR,类实例变量无法访问protected成员变量
- at.prot_fun(); //ERROR,类实例变量无法访问protected成员函数
- Atest();
- return 0;
- }
#include<string>
#include<iostream> using namespace std; class AccessTest { friend void Atest(); friend class CAtest; public: int pub_mem; void pub_fun(){} protected: int prot_mem; void prot_fun(){} private: int priv_memb; void priv_fun(){} }; class CAtest { public: void x() { AccessTest t; t.prot_fun(); //OK,友元类可以访问protected成员函数 int x=t.prot_mem; //OK,友元类可以访问protected成员变量 } }; void Atest() { AccessTest t; t.prot_fun(); //OK,友元函数可以访问protected成员函数 int x=t.prot_mem; //OK,友元函数可以访问protected成员变量 } int main() { AccessTest at; at.prot_mem; //ERROR,类实例变量无法访问protected成员变量 at.prot_fun(); //ERROR,类实例变量无法访问protected成员函数 Atest(); return 0; }
3:private访问权限
一个类的private成员变量、成员函数,无法通过类的实例变量进行访问。但是可以通过类的友元函数、友元类进行访问。
- #include<iostream>
- #include<string>
- using namespace std;
- class AccessTest
- {
- friend void Atest();
- friend class CAtest;
- public:
- int pub_mem;
- void pub_fun(){}
- protected:
- int prot_mem;
- void prot_fun(){}
- private:
- int priv_memb;
- void priv_fun(){}
- };
- class CAtest
- {
- public:
- void x()
- {
- AccessTest t;
- t.priv_fun(); //OK,友元类可以访问private成员函数
- int x=t.priv_memb; //OK,友元类可以访问private成员变量
- }
- };
- void Atest()
- {
- AccessTest t;
- t.priv_fun(); //OK,友元函数可以访问private成员函数
- int x=t.priv_memb; //OK,友元函数可以访问private成员变量
- }
- int main()
- {
- AccessTest at;
- at.priv_memb; //ERROR,类实例变量无法访问private成员变量
- at.priv_fun(); //ERROR,类实例变量无法访问private成员函数
- Atest();
- return 0;
- }
#include<iostream>
#include<string> using namespace std; class AccessTest { friend void Atest(); friend class CAtest; public: int pub_mem; void pub_fun(){} protected: int prot_mem; void prot_fun(){} private: int priv_memb; void priv_fun(){} }; class CAtest { public: void x() { AccessTest t; t.priv_fun(); //OK,友元类可以访问private成员函数 int x=t.priv_memb; //OK,友元类可以访问private成员变量 } }; void Atest() { AccessTest t; t.priv_fun(); //OK,友元函数可以访问private成员函数 int x=t.priv_memb; //OK,友元函数可以访问private成员变量 } int main() { AccessTest at; at.priv_memb; //ERROR,类实例变量无法访问private成员变量 at.priv_fun(); //ERROR,类实例变量无法访问private成员函数 Atest(); return 0; }
到现在,是否感觉私有访问属性,和保护属性没有什么区别?区别主要体现在继承上面。下面将会讲到。
总结:public在任何地方都能访问,protected只能在派生类中访问, private只能在友元中访问。
二:继承的访问权限控制
1:public继承
派生类通过public继承,基类的各种权限不变 。
派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
派生类的实例变量,可以访问基类的public成员,但是无法访问protected、private成员,仿佛基类的成员之间加到了派生类一般。
可以将public继承看成派生类将基类的public,protected成员囊括到派生类,但是不包括private成员。
- #include<iostream>
- #include<string>
- using namespace std;
- class AccessTest
- {
- public:
- int pub_mem;
- void pub_fun(){}
- protected:
- int prot_mem;
- void prot_fun(){}
- private:
- int priv_memb;
- void priv_fun(){}
- };
- class DAccessTest:public AccessTest
- {
- public:
- void test()
- {
- int x=pub_mem; //OK
- pub_fun(); //OK
- int y=prot_mem; //OK
- prot_fun(); //OK
- int z=priv_memb; //ERROR
- priv_fun(); //ERROR
- }
- };
- int main()
- {
- DAccessTest dt;
- int x=dt.pub_mem; //OK
- int y=dt.prot_mem; //ERROR
- int z=dt.priv_memb; //ERROR
- return 0;
- }
#include<iostream>
#include<string> using namespace std; class AccessTest { public: int pub_mem; void pub_fun(){} protected: int prot_mem; void prot_fun(){} private: int priv_memb; void priv_fun(){} }; class DAccessTest:public AccessTest { public: void test() { int x=pub_mem; //OK pub_fun(); //OK int y=prot_mem; //OK prot_fun(); //OK int z=priv_memb; //ERROR priv_fun(); //ERROR } }; int main() { DAccessTest dt; int x=dt.pub_mem; //OK int y=dt.prot_mem; //ERROR int z=dt.priv_memb; //ERROR return 0; }
2:protected继承
派生类通过protected继承,基类的public成员在派生类中的权限变成了protected 。protected和private不变。
派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
派生类的实例变量,无法访问基类的任何成员,因为基类的public成员在派生类中变成了protected。
可以将protected继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的protected成员,但是不包括private成员。
private成员是基类内部的隐私,除了友元,所有人员都不得窥探。派生类的友元,都不能访问
- #include<iostream>
- #include<string>
- using namespace std;
- class AccessTest
- {
- friend void Atest();
- friend class CAtest;
- public:
- int pub_mem;
- void pub_fun(){}
- protected:
- int prot_mem;
- void prot_fun(){}
- private:
- int priv_memb;
- void priv_fun(){}
- };
- class DAccessTest:protected AccessTest
- {
- public:
- void test()
- {
- int x=pub_mem; //OK
- pub_fun(); //OK
- int y=prot_mem; //OK
- prot_fun(); //OK
- int z=priv_memb; //ERROR
- priv_fun(); //ERROR
- }
- };
- int main()
- {
- DAccessTest dt;
- int x=dt.pub_mem; //ERROR,基类的成员现在是派生类的保护成员
- int y=dt.prot_mem; //ERROR,基类的成员现在是派生类的保护成员
- int z=dt.priv_memb; //ERROR
- return 0;
- }
#include<iostream>
#include<string> using namespace std; class AccessTest { friend void Atest(); friend class CAtest; public: int pub_mem; void pub_fun(){} protected: int prot_mem; void prot_fun(){} private: int priv_memb; void priv_fun(){} }; class DAccessTest:protected AccessTest { public: void test() { int x=pub_mem; //OK pub_fun(); //OK int y=prot_mem; //OK prot_fun(); //OK int z=priv_memb; //ERROR priv_fun(); //ERROR } }; int main() { DAccessTest dt; int x=dt.pub_mem; //ERROR,基类的成员现在是派生类的保护成员 int y=dt.prot_mem; //ERROR,基类的成员现在是派生类的保护成员 int z=dt.priv_memb; //ERROR return 0; }
3:private继承
派生类通过private继承,基类的所有成员在派生类中的权限变成了private。
派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
派生类的实例变量,无法访问基类的任何成员,因为基类的所有成员在派生类中变成了private。
可以将private继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的private成员,但是不包括private成员。
private成员是基类内部的隐私,除了友元,所有人员都不得窥探。派生类的友元,都不能访问
- #include<iostream>
- #include<string>
- using namespace std;
- class AccessTest
- {
- friend void Atest();
- friend class CAtest;
- public:
- int pub_mem;
- void pub_fun(){}
- protected:
- int prot_mem;
- void prot_fun(){}
- private:
- int priv_memb;
- void priv_fun(){}
- };
- class DAccessTest:private AccessTest
- {
- public:
- void test()
- {
- int x=pub_mem; //OK
- pub_fun(); //OK
- int y=prot_mem; //OK
- prot_fun(); //OK
- int z=priv_memb; //ERROR
- priv_fun(); //ERROR
- }
- };
- int main()
- {
- DAccessTest dt;
- int x=dt.pub_mem; //ERROR,基类的成员现在是派生类的私有成员
- int y=dt.prot_mem; //ERROR,基类的成员现在是派生类的私有成员
- int z=dt.priv_memb; //ERROR, private成员无法访问
- return 0;
- }
#include<iostream>
#include<string> using namespace std; class AccessTest { friend void Atest(); friend class CAtest; public: int pub_mem; void pub_fun(){} protected: int prot_mem; void prot_fun(){} private: int priv_memb; void priv_fun(){} }; class DAccessTest:private AccessTest { public: void test() { int x=pub_mem; //OK pub_fun(); //OK int y=prot_mem; //OK prot_fun(); //OK int z=priv_memb; //ERROR priv_fun(); //ERROR } }; int main() { DAccessTest dt; int x=dt.pub_mem; //ERROR,基类的成员现在是派生类的私有成员 int y=dt.prot_mem; //ERROR,基类的成员现在是派生类的私有成员 int z=dt.priv_memb; //ERROR, private成员无法访问 return 0; }
总结:继承修饰符,就像是一种筛子,将基类的成员筛到派生类。public、protected、private,就是筛子的眼。
通过public继承,所有基类成员(除了private),public、protected都到了派生类里面,public筛眼比较大,不会改变访问权限。
通过protected继承,所有基类成员(除了private),public、protected都到了派生类里面,protected筛眼大小适中,所有过来的成员都变成了protected。
通过private继承,所有基类成员(除了private),public、protected都到了派生类里面,private筛眼最小,所有过来的成员都变成了private。
PS:关于class和struct的区别
1:class不写修饰符,成员默认是private的,而struct 默认是public的
- class Base //默认private
- {
- int a;
- int b;
- }
- Base ba;
- int x=ba.a;//错误
- int y=ba.b;//错误
- struct St //默认public
- {
- int a;
- int b;
- };
- St st;
- int x=st.a; //OK
- int y=st.b;//OK
class Base //默认private
{
int a;
int b;
}
Base ba;
int x=ba.a;//错误
int y=ba.b;//错误
struct St //默认public
{
int a;
int b;
};
St st;
int x=st.a; //OK
int y=st.b;//OK
2:class的继承默认是private的,而struct默认是public的
- class Base{…};
- class Derive:Base{…} //private继承
- struct BStruct{…};
- struct DStruct:BStruct{…};//public继承
class Base{...};
class Derive:Base{...} //private继承
struct BStruct{...};
struct DStruct:BStruct{...};//public继承