概述
文章目录
- 三种访问权限
- public限定符
- private限定符
- protected限定符
- 继承与访问
- 友元与继承
- 改变个别成员的可访问性
- public继承与多态
- private继承
- final关键字
C++的三大特性之一——封装:隐藏对象的属性和实现细节,仅对外公开接口和对象进行交互,将数据和操作数据的方法进行有机结合。主要通过访问限定符:public/private/protected实现。
三种访问权限
public限定符
被public限定符所修饰的成员变量和函数可以被类的函数、子类的函数和对象、友元函数,也可以由类的对象来访问,即可以使用成员运算符(.或->)来访问。这里的友元函数,可以是该类的友元函数,也可以是该类的友元类的成员函数。
private限定符
被private限定符修饰的成员只能被该类的函数和友元函数访问,子类函数和对象无法访问,在这三个限定符中封装程度是最高的,一般来说,应该尽可能将类的成员变量声明为private而不是其他,减少成员变量的暴露,只提供getter和settter方法给外界访问,这样能提高类的安全性。
protected限定符
protected限定符修饰的成员变量和成员函数可以被 该类及其派生类 的成员函数和友元访问,但是不能被类对象(无论是基类还是派生类)所访问,即不能通过类对象的成员运算符(.或->)来访问。
继承与访问
某个类对其继承而来的成员的访间权限受到两个因素影响:一是在基类中该成员的访问说明符,二是在派生类的派生列表中的访问说明符。
派生访问说明符对于派生类的成员(及友元)能否访问其直接基类的成员没有影响。对基类成员的访问权限只与基类中的访问说明符有关:
class Base{
public:
void pub_mem();
protected:
int prot_mem;
private:
char priv_mem;
};
struct Pub_Derv: public Base{
//正确:派生类能访问protected成员
int f() { return prot_mem; }
//错误:private成员对于派生类来说不可访问
char g() { return priv_mem; }
};
struct Priv_Derv : private Base{
//private不影响派生类的访问权限
int f1() const { return prot_mem; }
}
派生访问说明符的目的是控制派生类对象(包括派生类的派生类在内)对于基类成员的访问权限:
Pub_Derv d1; //继承自Base的成员是public的
Priv_Derv d2; //继承自Base的成员是private的
d1.pub_mem(); //正确:pub_mem在派生类中是public的
d2.pub_mem(); //错误:pub_mem在派生类中是private的
派生访问说明符还可以控制继承自派生类的新类的访问权限:
struct Derived_from_Public : public Pub_Derv{
//正确:Base::prot_mem在Pub_Derv中仍然是protected的
int use_base() { return prot_mem; }
};
struct Derived_from_Private : public Priv_Derv{
//错误:Base::prot_mem在Priv_Derv中是private的
int use_base() { return prot_mem; }
};
struct Derived_from_Protected : protected Pub_Derv{
//正确:Base::prot_mem在Pub_Derv中仍然是protected的
int use_base() { return prot_mem; }
};
Derived_from_Public dfp;
dfp.pub_mem(); //正确
Derived_from_Protected dfpr;
dfpr.pub_mem(); //错误,Base的所有成员在派生类中是受保护的
公有、私有、受保护继承 相当于 将基类中的成员 加上对应访问权限放入派生类中:
-
若继承方式是public,基类成员在派生类中的访问权限保持不变,也就是说,基类中的成员访问权限,在派生类中仍然保持原来的访问权限;
-
若继承方式是private,基类所有成员在派生类中的访问权限都会变为私有(private)权限;
-
若继承方式是protected,基类的公有成员和保护成员在派生类中的访问权限都会变为保护(protected)权限,私有成员在派生类中的访问权限仍然是私有(private)权限。
友元与继承
就像友元关系不能传递一样(参见7.3.4节,第250页),友元关系同样也不能继承。
基类的友元在访问派生类成员时不具有特殊性,类似的,派生类的友元也不能随意访问基类的成员。
改变个别成员的可访问性
有时我们需要改变派生类继承的某个名字的访问级别,通过使用using声明可以达到这一目的:
class Base {
public:
size_t size() const { return n; }
protected:
size_t n;
};
class Derived : private Base {
public:
using Base::size;
protected:
using Base::n;
};
因为Derived使用了私有继承,所以继承而来的成员size和n(在默认情况下)是Derived的私有成员。然而,我们使用using声明语句改变了这些成员的可访问性。改变之后,Derived的用户将可以使用size成员,而Derived的派生类将能使用n。
派生类只能为那些它可以访问的名字提供using声明。
public继承与多态
只有当public继承时,才会展现多态,因为public继承意味“is-a”的关系:
如果你令class D以public继承class B,你便是告诉编译器:
- 每一个类型为D的对象同时也是一个类型为B的对象,编译器可以自动将class D转换为class B。反之不是
- B对象可使用的地方,D对象一样可以使用。反之不是
private继承
因为private继承的派生类对象无法被转换为基类对象,所以不能展现多态。
private
继承 意味implemented-in-terms-of(根据某物实现出) 。
如果你让class D以private形式继承class B,你的用意是为了采用class B内已经备妥的某些特性,不是因为B对象和D对象存在有任何观念上的关系。private
继承意味只有实现部分被继承,接口部分应略去。
implemented-in-terms-of也可以由复合实现。在应用域,复合意味着has-a;在实现域,复合意味着is-implemented-in-terms-of。尽可能使用复合实现这种关系,必要时(涉及protected成员或virtual函数时)才使用private继承。
参考:《Effective C++》条款 39:明智而审慎地使用private继承
final关键字
C++11的关键字final有两个用途:
- 放在类后阻止该类被继承;
- 放在虚函数后阻止该虚函数被覆盖。
参考:
https://www.cnblogs.com/chenwx-jay/p/9649108.html
https://blog.csdn.net/casky237/article/details/54766881
《C++primer 第五版》
最后
以上就是呆萌音响为你收集整理的C++ 访问控制与继承三种访问权限继承与访问的全部内容,希望文章能够帮你解决C++ 访问控制与继承三种访问权限继承与访问所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复