快速理解类的访问控制(public,protected,private)
接触过面向对象编程的朋友们都知道类中的访问控制符无非有三个,public, protected, private。
理解他就先从期望他达到的效果先说吧
Public: 使成员对于整个程序内(类内类外)都是可以访问的
Protected: 使派生类也可以访问其数据,但是又不想让其他的函数或类进行访问
Private: 只有他所在类的成员函数可以访问
在没有继承这一概念前,我们先只研究public与private就够了。
简单说,private实现的就是一种封装,让类的对象(C++primer里面叫类的用户)不能直接访问,而public让成员可以被程序的任何地方访问到。
比如:
class Base
{
public:
char a=’a’;
ChangeB(charmychar){return b= mychar };
enum num{
E_a,
E_b
}
private:
char b=’b’;
}
Base base1;
base1.a=’2’;//正确
base1.b=’2’;//错误,不能访问私有成员
base1.Show();//正确,实现了封装
Base:: num print(int tnum) //public 可以直接通过作用域访问
{
if(tnum==1) return E_a;
}
下面谈一下protected,在此之前简单说一下继承:定义相似的类型结构并以此进行建模,可以使设计的数据结构清晰易懂,同时可以实现封装和多态。简单举例来说,有一个动物的类型,里面包括老虎,狮子,猴子等,那可以把动物看做一个基类,猴子等看做一个派生类,猴子继承于动物类,可以实现更多更丰富的操作。其他有关继承概念的不在赘述~
Protected理解上就是private和public的中和,与private相似的是同样不能被类的对象(类的用户)访问,但是可以被派生类和友元访问。
下面有一个关于protected的比较难理解的结论:
派生类的成员或友元只能通过派生类对象来访问基类的受保护对象(即protected对象)。派生类对于一个基类对象中的受保护成员没有任何访问特权。
要解释这句话,首先要理解继承的机制,当一个派生类继承一个基类的时候,他就同时继承下来了基类的成员变量,也就是说这个类对象里面包含的不仅仅是自己的成员变量,还有基类的,而派生类构造的时候也要先执行基类的构造函数。
上面的”通过派生类对象来访问基类的受保护对象”意思就是可以通过基类的派生类对象访问该protected成员,因为派生类中包含基类的protected成员(继承下来的)。但是不可以直接通过访问基类对象来访问protected对象。下面举个例子:
class Base
{
protected:
char a=’a’;
}
class Son: public Base
{
voidprintBase(Base &b)
{
b.a=’1’; ///////错误,不能直接通过类访问protected成员
}
voidprintSon(Son &s)
{
s.a=’2’;
}
}
了解了类中作用域的访问控制,再看一下公有,私有,受保护的继承:
class Base
{
public:
char a=’a’;
changeB(char mychar){return b= mychar};
protected:
charb=’b’;
private:
char c=’c’;
}
struct Son1:public Base
{
CharreturnC(){ return c;} ////错误,私有变量只有类内部成员可以访问
CharreturnB(){ return b;}
CharreturnA(){ return a;}
}
struct Son2:private Base
{
charreturnC(){ return c;} ////错误,私有变量只有类内部成员可以访问
charreturnB(){ return b;} //private继承不影响派生类对基类的访问权限
charreturnA(){ return a;}
}
Son1 s1;
Son2 s2;
s1.returnA(); //正确,a在派生类Son1中是public的
s2.returnA(); //错误,a在派生类Son2中是privat的
这里要知道的是,派生类的继承访问控制影响的是派生类中成员的访问权限,不影响派生类访问基类的权限。也就是说,基类的访问控制没有变化,而派生类可以理解成下面这样~
struct Son1:public Base
{
public:
char a=’a’;
protected:
char b=’b’;
}
struct Son2:private Base
{
private:
chara=’a’;
char b=’b’;
}
所以,这时候son1的对象(用户)可以访问到a,但是son2的对象不能访问到a了。
可以把这个理解为 public继承原来的访问权限都不变,protected继承就’降级’,private就变为都是私有的。
如果细心的话可能注意到两点疑问:
1. 为什么我的Son1和Son2里面没有写char
c?
2. Struct继承class如何理解?
答1:我们知道,子类根本没有权限访问父类的private,所以派生类根本就没有c这个字符串。(不过我理解可能调用基类构造函数的时候也初始化了c,然而被隐藏起来)
答2:struct和class在C++中都可以是类声明的关键字,实质上没有什么差别。唯一的区别就是struct类中的成员默认是public的。而class内的成员默认是private的。当然,我们平时也可以把struct当成c语言中的结构体来使用。
补充:假设a继承于b
1只有a公共的继承基类时,用户代码才能使用派生类向基类转换。
2 a如果是公共继承或受保护继承的,则a的派生类的成员可以使用a到b的类型转换
快速理解类的访问控制(public,protected,private)的更多相关文章
- 访问控制public/protected/private的区别
Java支持四种不同的访问权限: 修饰符 说明 public 共有的,对所有类可见. protected 受保护的,对同一包内的类和所有子类可见. private 私有的,在同一类内可见. 默认的 在 ...
- C++ 访问控制 public, protected, private, 友元
1. 变量属性与继承之间的关系 #include <iostream> using namespace std; class A { public: int x; protected: i ...
- 【转】C++易混知识点5:实例讲解Public Protected Private作用域,继承的区别和用意
大学生涯,涉及到类的作用域,继承都是用的public 共有继承,当时也没想那么多,觉得共有继承多方便,多简单,反正没有太多的限制,不管是类的成员或者是基类的成员函数都可以访问.没有深究.其实这里面真是 ...
- C++ 类访问控制(public/protected/private)
第一:private, public, protected 访问标号的访问范围. private:只能由1.该类中的函数.2.其友元函数访问. 不能被任何其他访问,该类的对象也不能访问. protec ...
- C++中public,protected,private派生类继承问题和访问权限问题
C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...
- 【转载】C++中public,protected,private访问
第一:private, public, protected 访问标号的访问范围. 假如我们约定: 类内部-----指的是当前类类型的定义中,以及其成员函数的声明和定义中: 类外部-----指的是不在当 ...
- JAVA修饰符类型(public,protected,private,friendly)
转自:http://www.cnblogs.com/webapplee/p/3771708.html JAVA修饰符类型(public,protected,private,friendly) publ ...
- JAVA类型修饰符(public,protected,private,friendly)
JAVA类型修饰符(public,protected,private,friendly) public的类.类属变量及方法.包内及包外的不论什么类均能够訪问:protected的类.类属变量及方法,包 ...
- C++:继承访问属性(public/protected/private)
• 公有继承(public) 公有继承在C++中是最常用的一种继承方式,我们先来看一个示例: #include<iostream> using namespace std; class F ...
随机推荐
- Disk array controller and information processing apparatus
A disk array controller has a function of relocating a plurality of data blocks stored in a disk arr ...
- Android设备与外接U盘实现数据读取操作
现在越来越多手机支持OTG功能,通过OTG可以实现与外接入的U盘等USB设备实现数据传输.关于OTG,可以参考: http://blog.csdn.net/srw11/article/details/ ...
- Java--分布式系统高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- Power management in semiconductor memory system
A method for operating a memory module device. The method can include transferring a chip select, co ...
- QSplitter实现自由伸缩滑动窗口部件(要在m_pSplitter中加入frame_4之前,给frame_4设置样式;之后设置无效)
实现代码如下: #include <QSplitter> QSplitter *m_pSplitter; m_pSplitter = new QSplitter(ui->frame_ ...
- 中英文对照 —— 互联网、IT(信息科技)、编程
1. 网站 web-portal:门户网站: 2. 工具与方法 crowdsourcing:众包, crowd ⇒ 众: 3. 软件 MVP:最小化可行产品,Minimum Viable Produc ...
- XF 通过判断平台加载不同的图片
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- WPF 使用Propereties:Resources.resx里面的资源
<Window x:Class="Wpf180706.Window7" xmlns="http://schemas.microsoft.com/win ...
- WPF自定义控件步骤
1 .在类库里面添加system.xaml的引用,给控件指定Name: 2.设计控件的外观,并将内部元素绑定到控件类的属性:此时即使没有在类中增加相关属性也不会报错,xaml类似html错误只是不显示 ...
- QT 等待对话框/进度--
用QT的,加载的一张gif图片.记录下来以后免得忘记. #ifndef DIALOG_H #define DIALOG_H #include <QDialog> #include < ...