接触过面向对象编程的朋友们都知道类中的访问控制符无非有三个,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)的更多相关文章

  1. 访问控制public/protected/private的区别

    Java支持四种不同的访问权限: 修饰符 说明 public 共有的,对所有类可见. protected 受保护的,对同一包内的类和所有子类可见. private 私有的,在同一类内可见. 默认的 在 ...

  2. C++ 访问控制 public, protected, private, 友元

    1. 变量属性与继承之间的关系 #include <iostream> using namespace std; class A { public: int x; protected: i ...

  3. 【转】C++易混知识点5:实例讲解Public Protected Private作用域,继承的区别和用意

    大学生涯,涉及到类的作用域,继承都是用的public 共有继承,当时也没想那么多,觉得共有继承多方便,多简单,反正没有太多的限制,不管是类的成员或者是基类的成员函数都可以访问.没有深究.其实这里面真是 ...

  4. C++ 类访问控制(public/protected/private)

    第一:private, public, protected 访问标号的访问范围. private:只能由1.该类中的函数.2.其友元函数访问. 不能被任何其他访问,该类的对象也不能访问. protec ...

  5. C++中public,protected,private派生类继承问题和访问权限问题

    C++中public,protected,private派生类继承问题和访问权限问题 当一个子类从父类继承时,父类的所有成员成为子类的成员,此时对父类成员的访问状态由继承时使用的继承限定符决定. 1. ...

  6. 【转载】C++中public,protected,private访问

    第一:private, public, protected 访问标号的访问范围. 假如我们约定: 类内部-----指的是当前类类型的定义中,以及其成员函数的声明和定义中: 类外部-----指的是不在当 ...

  7. JAVA修饰符类型(public,protected,private,friendly)

    转自:http://www.cnblogs.com/webapplee/p/3771708.html JAVA修饰符类型(public,protected,private,friendly) publ ...

  8. JAVA类型修饰符(public,protected,private,friendly)

    JAVA类型修饰符(public,protected,private,friendly) public的类.类属变量及方法.包内及包外的不论什么类均能够訪问:protected的类.类属变量及方法,包 ...

  9. C++:继承访问属性(public/protected/private)

    • 公有继承(public) 公有继承在C++中是最常用的一种继承方式,我们先来看一个示例: #include<iostream> using namespace std; class F ...

随机推荐

  1. Codeforces 444A DZY Loves Physics(图论)

    题目链接:Codeforces 444A DZY Loves Physics 题目大意:给出一张图,图中的每一个节点,每条边都有一个权值.如今有从中挑出一张子图,要求子图联通,而且被选中的随意两点.假 ...

  2. Java中,对多线程访问同一变量(并发访问)的认识

    在Java中,如果启动多个线程对同一个对象或者变量时候,在没有安全保护前提下有可能会抛出并异常 java.util.ConcurrentModificationException 当方法检测到对象的并 ...

  3. 它们的定义Activity跳转动画

    本来觉得是一个非常小的需求, 后来我发现总是 错误, 采用Theme于 4.0在 操作不是很容易使用. 后来查阅资料, 须要在finish 后面 和 startActivity 后面加入 overri ...

  4. 1.通过模板创建MAP版本项目

    1.选择mpa+ef+module-zero 取名字 2.用vs打开项目后,在解决方案上右键 还原nuget包 3.打开程序包管理器控制台,选择以EntityFramework结尾的项目,并执行upd ...

  5. ASP.NET Core Windows 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Windows 环境配置 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Windows 环境配置 ASP.NET Core ...

  6. WPF绘制深度不同颜色的3D模型填充图和线框图

    原文:WPF绘制深度不同颜色的3D模型填充图和线框图 在机械测量过程中,测量的数据需要进行软件处理.通常测量一个零件之后,需要重建零件的3D模型,便于观察测量结果是否与所测工件一致. 重建的3D模型需 ...

  7. qt线程(转)----这篇很专业!

    本文档是自己所整理的一份文档,部分是原创,还转贴了网上的一此资料(已经标明了),(难点是多线程的编写),是有源代码的,大家可以作为参考,用到的知识是视频采集,压缩解压(xvid),实时传输(jrtp) ...

  8. spring boot 集成mybatis报错Missing artifact

    1. pom文件中的oracle依赖提示Missing artifact,需要手动下载并导入maven参考 oracle依赖下载地址 (ojdbc6.jar) cd到下载的ojdbc6.jar所在路径 ...

  9. springboot 使用日志

    spring boot 默认使用日志打印到console 添加application.properties文件在src/main/resoures文件夹下 logging.file=my.log 将日 ...

  10. WPF listview item mouse enter/over popup

    This is because the routing strategy of the Loaded event is Direct, which means that the routed even ...