【C++学习笔记】访问控制方式

0x00 前言

文章中的文字可能存在语法错误以及标点错误,请谅解;

如果在文章中发现代码错误或其它问题请告知,感谢!

本文档为个人边学习边记录的C++笔记,非教程,笔记中会存在引用他人文章内容的部分,被引用的原文不会被特殊标记出来,但会在参考文档中给出原文链接。

0x01 公有继承

当类的继承方式为公有继承时,基类的公有成员和保护成员的访问属性在派生类中不变,而基类的私有成员不可直接访问。

在族类之外只能通过派生类的对象访问从基类继承的公有成员,而无论是派生类成员还是派生类的对象都无法直接访问基类的私有成员。

例:从Point类派生出新的Rectangle(矩形)类。
在这里插入图片描述Point类和Rectangle类的继承关系的UML图形表示

Point.h:

#ifndef _POINT_H_
#define _POINT_H_

class Point{
public:
	void initPoint(float x = 0, float y = 0){this->x = x;this->y = y;}
	void move(float offX, float offY){x += offX; y += offY;}
	float getX() const {return x;}
	float getY() const {return y;}
private:
	float x, y;
};
#endif

Rectangle.h:

#ifndef _RECTANGLE_H_
#define _RECTANGLE_H_
#include"Point.h"
class Rectangle:public Point{
public:
	void initRectangle(float x, float y, float w, float h){
		initPoint(x, y);
		this->w = w;
		this->h = h;
	}
	float getH() const {return h;}
	float getW() const {return w;}
private:
	float w, h;
};
#endif

7-1.cpp:

#include<iostream>
#include<cmath>
#include"Rectangle.h"
#include"Point.h"
using namespace std;

int main(){
	Rectangle rect;
	rect.initRectangle(2, 3, 20, 10);
	rect.move(3, 2);
	cout << "The date of rect(x, y, w, h):" << endl;
	cout << rect.getX() << ","
		<< rect.getY() << ","
		<< rect.getW() << ","
		<< rect.getH() << endl;
	return 0;
}

运行结果:

The date of rect(x, y, w, h):
5,5,20,10

这里定义基类Point。派生类Rectangle继承了Point类的全部成员(隐含的默认构造和析构函数除外),因此在派生类中,实际所拥有的成员就是从基类继承过来的成员和派生类新定义成员的总和。继承方式为公有继承,这时,基类的公有成员在派生类中的访问属性保持原样,派生类的成员函数及对象可以访问到基类的公有成员(派生类函数成员initRectangle中直接调用基类函数initPoint),但是无法访问基类的私有成员(基类的x,y)。基类原有的外部接口(基类的getX()和getY()函数)变成了派生类外部接口的一部分。当然,派生类自己新增的成员之间都是可以互相访问的。
Rectangle类继承了Point类的成员,也就实现了代码的重用,同时通过新增成员,加入了自身独有的特征,达到了程序的扩充。

0x02 私有继承

当类的继承方式为私有继承时,基类中的公有成员和保护成员都可以以私有身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。

基类的公有成员和保护成员被继承后作为派生类的私有成员,派生类的其他成员可以直接访问它们,但是在类族外面通过派生类的对象无法直接访问它们。无论是派生类的成员还是通过派生类的对象,都无法直接访问基类继承的私有成员。

经过私有继承之后,所有基类的成员都为了派生类的私有成员或不可直接访问的成员,如果进一步派生的话,基类的全部成员就无法再新的派生类中被直接访问。因此,私有继承之后,基类的成员再也无法在以后的派生类中直接发挥作用,实际是相当于终止了基类功能的继续派生,出于这种原因,一般情况下私有继承的使用比较少。

例:Point类私有继承

Point.h:

#ifndef _POINT_H_
#define _POINT_H_

class Point{
public:
	void initPoint(float x = 0, float y = 0){this->x = x;this->y = y;}
	void move(float offX, float offY){x += offX; y += offY;}
	float getX() const {return x;}
	float getY() const {return y;}
private:
	float x, y;
};
#endif

Rectangle.h:

#ifndef _RECTANGLE_H_
#define _RECTANGLE_H_
#include"Point.h"
class Rectangle:private Point{
public:
	void initRectangle(float x, float y, float w, float h){
		initPoint(x, y);
		this->w = w;
		this->h = h;
	}
	void move(float offX, float offY){Point::move(offX, offY);}
	float getX() const {return Point::getX();}
	float getY() const {return Point::getY();}
	float getH() const {return h;}
	float getW() const {return w;}
private:
	float w, h;
};
#endif

7-2.cpp:

#include<iostream>
#include<cmath>
#include"Rectangle.h"
#include"Point.h"
using namespace std;

int main(){
	Rectangle rect;
	rect.initRectangle(2, 3, 20, 10);
	rect.move(3, 2);
	cout << "The date of rect(x, y, w, h):" << endl;
	cout << rect.getX() << ","
		<< rect.getY() << ","
		<< rect.getW() << ","
		<< rect.getH() << endl;
	return 0;
}

运行结果:

The date of rect(x, y, w, h):
5,5,20,10

继承方式为私有继承,这时,基类中的共有和保护成员在派生类中都已私有成员的身份出现。派生类的成员函数及对象无法访问基类的私有成员(例如基类的x,y)。派生类的成员仍然可以访问到从基类击沉过来的公有和保护成员(例如在派生类函数成员initRectangle中直接调用基类的函数initPoint),但是在类外部通过派生类的对象根本无法直接访问到基类的任何成员,基类原有的外部接口(例如基类的getX()和getY()函数)被派生类封装和隐藏起来。当然,派生类新增的成员之间仍然可以自由的互相访问。

在私有继承情况下,为了保证基类对的一部分接口特征能够在派生类中也存在,就必须在派生类中重新声明同名函数。这里在派生类Rectangle中,重新声明了move,getX,getY等函数,利用派生类对基类成员的保护能力,把基类的原有成员函数的功能照搬出来。

0x03 保护继承

保护继承中,基类的公有成员和保护成员都以保护成员的身份出现在派生类中,而基类的私有成员不可直接访问。这样派生类的其他成员就可以直接访问从基类继承来的公有和保护成员,但在类外部通过派生类的对象无法直接访问它们。无论是派生类成员还是派生类的对象都无法直接访问基类的私有对象。

《C++语言程序设计(第4版)》书上所有章节出现的示例源代码随着学习的深入会陆续上传至github,代码为个人手动输入并通过编译,有的示例代码可能没有注释:https://github.com/fyw4/C-plus-plus-learning-example

以上。

参考文档:
郑莉 董渊 何江舟.《C++语言程序设计(第4版)》[M].北京:清华大学出版社。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值