一、用法说明

1.类的一个特征就是封装,public和private作用就是实现这一目的。所以:

用户代码(类外)可以访问public成员而不能访问private成员;private成员只能由类成员(类内)和友元访问。

2.类的另一个特征就是继承,protected的作用就是实现这一目的。所以:

protected成员可以被派生类对象访问,不能被用户代码(类外)访问。

二、理解与实践

先从类定义里理解public, 定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。

类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。例如,我们使用关键字 class 定义 Box 数据类型,如下所示:

class Box
{public:double length;   // 盒子的长度double breadth;  // 盒子的宽度double height;   // 盒子的高度
};

关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。
多说一点:

以上的类class类似结构体,因此不同的结构体名可共用类Box,并且对象 Box1 和 Box2 都有它们各自的数据成员:

Box Box1;          // 声明 Box1,类型为 Box
Box Box2;          // 声明 Box2,类型为 Box

参考文献:C++使用技巧(三):C++基类 & 派生类

谭浩强的《C++程序设计》中关于public,private和protected这三个成员访问限定符的概念性解释:

如果在类的定义中既不指定private,也不指定public,则系统就默认为是私有的。

被声明为私有的(private)成员,只能被本类中的成员函数引用,类外不能调用(友元类除外)。

被声明为公用的(public)成员,既可以被本类中的成员函数所引用,也可以被类的作用域内的其他函数引用。

用protected声明的成员称为受保护的成员,它不能被类外访问(这点与私有成员类似),但可以被派生类的成员函数访问。

3、 关于public、protect、private的访问权限控制

参考文献:
参考原文
一:成员的访问权限
1: 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;
}

2:protected访问权限
一个类的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;
}

3: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只能在派生类中访问, private只能在友元中访问。

二:继承的访问权限控制
1:public继承
派生类通过public继承,基类的各种权限不变 。

 派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。派生类的实例变量,可以访问基类的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;     //OKpub_fun();         //OKint y=prot_mem;    //OKprot_fun();        //OKint z=priv_memb;   //ERRORpriv_fun();        //ERROR}};int main()
{DAccessTest dt;int x=dt.pub_mem;    //OKint y=dt.prot_mem;   //ERRORint z=dt.priv_memb;  //ERRORreturn 0;
}

2:protected继承
派生类通过protected继承,基类的public成员在派生类中的权限变成了protected 。protected和private不变。
派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

 派生类的实例变量,无法访问基类的任何成员,因为基类的public成员在派生类中变成了protected。可以将protected继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的protected成员,但是不包括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:protected AccessTest
{public:void test(){int x=pub_mem;     //OKpub_fun();         //OKint y=prot_mem;    //OKprot_fun();        //OKint z=priv_memb;   //ERRORpriv_fun();        //ERROR}};int main()
{DAccessTest dt;int x=dt.pub_mem;    //ERROR,基类的成员现在是派生类的保护成员int y=dt.prot_mem;   //ERROR,基类的成员现在是派生类的保护成员int z=dt.priv_memb;  //ERRORreturn 0;
}

3:private继承

 派生类通过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;     //OKpub_fun();         //OKint y=prot_mem;    //OKprot_fun();        //OKint z=priv_memb;   //ERRORpriv_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;
}

总结:继承修饰符,就像是一种筛子,将基类的成员筛到派生类。public、protected、private,就是筛子的眼。

      通过public继承,所有基类成员(除了private),public、protected都到了派生类里面,public筛眼比较大,不会改变访问权限。通过protected继承,所有基类成员(除了private),public、protected都到了派生类里面,protected筛眼大小适中,所有过来的成员都变成了protected。通过private继承,所有基类成员(除了private),public、protected都到了派生类里面,private筛眼最小,所有过来的成员都变成了private。

PS:关于class和struct的区别
1:class不写修饰符,成员默认是private的,而struct 默认是public的

class Base   //默认private
{int a;int b;
}Base ba;
int x=ba.a;//错误
int y=ba.b;//错误struct St  //默认public
{int a;int b;
};St st;
int x=st.a; //OK
int y=st.b;//OK

2:class的继承默认是private的,而struct默认是public的

class Base{...};
class Derive:Base{...}  //private继承struct BStruct{...};
struct DStruct:BStruct{...};//public继承

C++使用技巧(五):C类public,protected和 private的用法相关推荐

  1. 类的成员包含 java_Java 面向对象(十五)类的成员 之 内部类

    一.内部类 1.引入 类的成员包括: (1)属性:成员变量: (2)方法:成员方法: (3)构造器: (4)代码块: (5)内部类: 其中1.2是代表这类事物的特征: 其中3.4是初始化类和对象用的: ...

  2. java friendly 子包,黑馬程序員 java 修飾符類型(public,protected,private,friendly)

    這四個作用域的可見范圍如下表所示. 說明:如果在修飾的元素上面沒有寫任何訪問修飾符,則表示friendly. 作用域    當前類 同一package 子孫類 其他package public   √ ...

  3. java中的private public protected

    1.public:public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直 ...

  4. C++学习 十五、类继承(1)基类,派生类,访问权限,protected

    C++学习 十五.类继承(1)基类,派生类 前言 类继承 类的关系与继承 基类, 派生类 基类 派生类 构造函数,析构函数 文件位置 访问权限 protected 后记 前言 本篇开始学习C++类的继 ...

  5. C++ 笔记(16)— 类和对象(类定义、类实例对象定义、访问类成员、类成员函数、类 public/private/protected 成员、类对象引用和指针)

    1. 类的定义 类定义是以关键字 class 开头,后跟类的名称.并在它后面依次包含类名,一组放在 {} 内的成员属性和成员函数,以及结尾的分号. 类声明将类本身及其属性告诉编译器.类声明本身并不能改 ...

  6. 类中的关键字public、protected、private究竟是什么意思?

    类中的关键字public.protected.private究竟是什么意思? 这三个关键字用来修饰类中的成员的有效域,即成员在哪个域内是可被调用的.下面我们来仔细说明这句话. 所谓"类中的成 ...

  7. C++ 类访问控制(public/protected/private)小结

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

  8. php protected 的继承,14 PHP 类的继承 [public protected private] parent 构造方法 析构方法 重写 最终类和方法 设计模式...

    类的继承 简单理解: 某个类A具有某些特征,另一个类B,也具有A类的所有特征,并且还可能具有自己的更多的一些特征,此时,我们就可以实现:B类使用A的特征信息并继续添加自己的一些特有特征信息. 基本概念 ...

  9. abstract类中不可以有private的成员_C++类成员的三种访问权限:public/protected/private...

    1.访问限定符 C++ 通过 public.protected.private 三个关键字来控制成员变量和成员函数的访问权限(也称为可见性),分别表示:公有的.受保护的.私有的. class 2.访问 ...

最新文章

  1. mysql 5.5 declare_MySQL5新语句declare的用法
  2. exchange 2013 升级CU15,提示“上次安装完成后没有重启”的提示
  3. 中国风力发电设备市场需求容量与投资战略研究报告2022版
  4. 模块计算机型x86yu,ldd3学习之九:与硬件通信
  5. vue图片点击超链接_vue使用v-for实现hover点击效果
  6. 这场论文复现的华山论剑,谁能拔得头筹
  7. 「Ubuntu」系统常用命令
  8. 基础 - jQuery选项卡
  9. vs mysql iss_MySQL5.7与8.0的连接问题(vs2015\2017)
  10. python如何调用阿里云接口_Python调用aliyun API设置阿里云负载均衡虚拟服务器组权重...
  11. “你”“我”“他”在Unicode表中的位置。
  12. 五线谱音名和组别对照表_五线谱最全知识及符号! 太实用了,100%收藏!!!...
  13. IDEA使用database时,连接MySQL后schemas不显示数据库名的情况
  14. 牛客网:牛牛送冰淇淋
  15. 计算机网络——(3)网络体系结构和协议
  16. 【微信小程序】零基础学 | 小程序语法
  17. soc 设计soc设计 uml实务手册_企业内训“软件需求设计建模方法学全程实例剖析”训练方案(2020年)...
  18. 道客巴巴免费下载文档技巧
  19. Springboot毕业设计毕设作品,校园网站系统设计与实现
  20. ncnn之一:ncnn概述

热门文章

  1. Centos7下team在roundrobin以及activebackup状态下对于iscsi target的性能影响
  2. 人工智能知识全面讲解: 什么问题适合用机器学习方法解决?
  3. Ubuntu的Kdump
  4. elasticsearch 报链接错误
  5. joke整人代码瘫痪_分析瘫痪:过度思考和了解太多代码
  6. kali linux arp欺骗钓鱼wifi
  7. (总结)Django 高性能ORM 查询优化
  8. 蓝牙BLE 的几个坑与心得!
  9. jsoup 的用法网络爬虫
  10. 从零开始学习信号完整性-9-电平接口(2)