C++中关于public/protect/private的访问权限控制
2017-12-20
成员的访问权限
- 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;
}
- protect访问权限
一个类的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;
}
- 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;
}
私有访问属性和保护属性的区别主要体现在继承上。总结:public在任何地方都能访问,protected只能在派生类中访问,privete只能在友元中访问。
继承的访问权限
- public继承
派生类通过public继承,基类各个权限不变。
派生类的成员函数,可以访问基类的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;
}
- protected 继承
派生类通过protected继承,基类的public成员在派生类中的权限变成了protected。protected和private不变。
派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。
派生类的实例变量,无法访问基类的任何成员,因为基类的public成员在派生类中变成了protected。
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;
}
- private继承
p派生类通过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;
}
关于class和struct的区别
-
class不写修饰符,成员默认是private的;而struct默认是public的
-
class的继承默认是private的,而struct默认是public的