public private protected
初学C++的朋友经常在类中看到public,protected,private以及它们在继承中表示的一些访问范围,很容易搞糊涂。今天本文就来十分分析一下C++中public、protected及private用法。相信对于大家深入掌握C++程序设计会有很大的帮助。
这里我们首先要明白下面几点。
1.类的一个特征就是封装,public和private作用就是实现这一目的。所以:
用户代码(类外)可以访问public成员而不能访问private成员;private成员只能由类成员(类内)和友元访问。
2.类的另一个特征就是继承,protected的作用就是实现这一目的。所以:
protected成员可以被派生类对象访问,不能被用户代码(类外)访问。
现来看看如下示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#include<iostream>#include<assert.h>using namespace std;class A{public: int a; A(){ a1 = 1; a2 = 2; a3 = 3; a = 4; } void fun(){ cout << a << endl; //正确 cout << a1 << endl; //正确 cout << a2 << endl; //正确,类内访问 cout << a3 << endl; //正确,类内访问 }public: int a1;protected: int a2;private: int a3;};int main(){ A itema; itema.a = 10; //正确 itema.a1 = 20; //正确 itema.a2 = 30; //错误,类外不能访问protected成员 itema.a3 = 40; //错误,类外不能访问private成员 system("pause"); return 0;} |
继承中的特点:
先记住:不管是否继承,上面的规则永远适用!
有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。
1.public继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:public, protected, private
2.protected继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:protected, protected, private
3.private继承:基类public成员,protected成员,private成员的访问属性在派生类中分别变成:private, private, private
但无论哪种继承方式,上面两点都没有改变:
1.private成员只能被本类成员(类内)和友元访问,不能被派生类访问;
2.protected成员可以被派生类访问。
再来看看以下代码:
1.public继承
代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include<iostream>#include<assert.h>using namespace std;class A{public: int a; A(){ a1 = 1; a2 = 2; a3 = 3; a = 4; } void fun(){ cout << a << endl; //正确 cout << a1 << endl; //正确 cout << a2 << endl; //正确 cout << a3 << endl; //正确 }public: int a1;protected: int a2;private: int a3;};class B : public A{public: int a; B(int i){ A(); a = i; } void fun(){ cout << a << endl; //正确,public成员 cout << a1 << endl; //正确,基类的public成员,在派生类中仍是public成员。 cout << a2 << endl; //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。 cout << a3 << endl; //错误,基类的private成员不能被派生类访问。 }};int main(){ B b(10); cout << b.a << endl; cout << b.a1 << endl; //正确 cout << b.a2 << endl; //错误,类外不能访问protected成员 cout << b.a3 << endl; //错误,类外不能访问private成员 system("pause"); return 0;} |
2.protected继承:
代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include<iostream>#include<assert.h>using namespace std;class A{public: int a; A(){ a1 = 1; a2 = 2; a3 = 3; a = 4; } void fun(){ cout << a << endl; //正确 cout << a1 << endl; //正确 cout << a2 << endl; //正确 cout << a3 << endl; //正确 }public: int a1;protected: int a2;private: int a3;};class B : protected A{public: int a; B(int i){ A(); a = i; } void fun(){ cout << a << endl; //正确,public成员。 cout << a1 << endl; //正确,基类的public成员,在派生类中变成了protected,可以被派生类访问。 cout << a2 << endl; //正确,基类的protected成员,在派生类中还是protected,可以被派生类访问。 cout << a3 << endl; //错误,基类的private成员不能被派生类访问。 }};int main(){ B b(10); cout << b.a << endl; //正确。public成员 cout << b.a1 << endl; //错误,protected成员不能在类外访问。 cout << b.a2 << endl; //错误,protected成员不能在类外访问。 cout << b.a3 << endl; //错误,private成员不能在类外访问。 system("pause"); return 0;} |
3.private继承:
代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
#include<iostream>#include<assert.h>using namespace std;class A{public: int a; A(){ a1 = 1; a2 = 2; a3 = 3; a = 4; } void fun(){ cout << a << endl; //正确 cout << a1 << endl; //正确 cout << a2 << endl; //正确 cout << a3 << endl; //正确 }public: int a1;protected: int a2;private: int a3;};class B : private A{public: int a; B(int i){ A(); a = i; } void fun(){ cout << a << endl; //正确,public成员。 cout << a1 << endl; //正确,基类public成员,在派生类中变成了private,可以被派生类访问。 cout << a2 << endl; //正确,基类的protected成员,在派生类中变成了private,可以被派生类访问。 cout << a3 << endl; //错误,基类的private成员不能被派生类访问。 }};int main(){ B b(10); cout << b.a << endl; //正确。public成员 cout << b.a1 << endl; //错误,private成员不能在类外访问。 cout << b.a2 << endl; //错误, private成员不能在类外访问。 cout << b.a3 << endl; //错误,private成员不能在类外访问。 system("pause"); return 0;} |
通过以上的代码都备有较为详尽的注释,读者应该能够理解。仔细看代码中派生类B中定义了和基类同名的成员a,此时基类的a仍然存在,可以验证。
|
1
2
3
4
5
6
7
|
int main(){ cout << sizeof(A) << endl; cout << sizeof(B) << endl; system("pause"); return 0;} |
输出:
16
20
所以派生类包含了基类所有成员以及新增的成员,同名的成员被隐藏起来,调用的时候只会调用派生类中的成员。
如果要调用基类的同名成员,可以用以下方法:
|
1
2
3
4
5
6
7
8
9
|
int main(){ B b(10); cout << b.a << endl; cout << b.A::a << endl; system("pause"); return 0;} |
输出:
10
4
记得这里是在类外访问,而a在基类中是public,所以继承方式应该为public,使得a在派生类中仍然为public,在类外可以访问。
感兴趣的读者可以调试运行一下本文实例,加深印象的同时还会有新的收获。
public private protected的更多相关文章
- public/private/protected访问控制权限的区别
//public/private/protected访问控制权限的区别//时间:2016/8/16 //(一)修饰成员: //public: 在类内.类外都能使用 . //protected: 在类内 ...
- Java中public,private,protected,和默认的区别
Java中public,private,protected,和默认的区别 1.private修饰词,表示成员是私有的,只有自身可以访问: 2.protected,表示受保护权限,体现在继承,即子类可以 ...
- 深入浅出OOP(五): C#访问修饰符(Public/Private/Protected/Internal/Sealed/Constants)
访问修饰符(或者叫访问控制符)是面向对象语言的特性之一,用于对类.类成员函数.类成员变量进行访问控制.同时,访问控制符也是语法保留关键字,用于封装组件. Public, Private, Protec ...
- public private protected和默认的区别(转自百度)
public private protected和默认的区别 Java中对类以及类中的成员变量和成员方法通过访问控制符(access specifier)进行区分控制.刚学Java语言的同学可能对pu ...
- php class中public,private,protected的区别,以及实例
一,public,private,protected的区别 public:权限是最大的,可以内部调用,实例调用等. protected: 受保护类型,用于本类和继承类调用. private: 私有类型 ...
- public,private,protected的区别
一,public,private,protected的区别public:权限是最大的,可以内部调用,实例调用等.protected: 受保护类型,用于本类和继承类调用.private: 私有类型,只有 ...
- 访问权限系列一(public/private/protected/default):成员变量
通过两个程序包对自身或互相之间的访问,得到结果.(先编译Test_01,得到class文件,通过Test的集中访问情况) 如下Test.java中内容: package com.java; /* * ...
- PHP中public,private,protected,abstract等关键字用法详解
PHP中常用的关键字 在PHP中包含了很多对函数和类进行限制的关键字,常用的通常有abstract,final,interface,public,protected,private,static等等, ...
- public private protected default
public private protected default 这几个限定访问控制符只是在编译阶段起作用,在运行阶段不起作用 private修饰符 , 本类可以访问 default修饰符 , 本类, ...
- PHP中const,static,public,private,protected的区别
原文地址:http://small.aiweimeng.top/index.php/archives/54.html const: 定义常量,一般定义后不可改变static: 静态,类名可以访问pub ...
随机推荐
- android学习一(了解android)
声明:android学习文件中面的全部内容为都是整理来自第一行代码Android.在接下来的文章里我就不在进行反复的声明. 想看原版的能够买书看看.或者去作者的博客http://blog.csdn.n ...
- shell 爬虫 从日志分析到数据采集与分析
[root@VM_61_158_centos ~]# curl http://ip.chinaz.com/220.112.233.179 |grep -e Whwtdhalf.*span.*span. ...
- QVariant(相当于是Java里面的Object,是万能的容器,但要注册)
这个类型相当于是Java里面的Object,它把绝大多数Qt提供的数据类型都封装起来,起到一个数据类型“擦除”的作用.比如我们的 table单元格可以是string,也可以是int,也可以是一个颜色值 ...
- C#中,JSON字符串转换成对象。
在前台提交(post)的数据中.除了强类型的数据外,还有一个额外的json数据提交 在这里我的办法是,在前台把json对象转换成字符串,然后提交. 测试demo 前台: @using(Html.Beg ...
- P2465 [SDOI2008]山贼集团 dp
这个题是一道树形dp+状压dp二合一,先预处理每种组合会有什么额外的费用,然后在树上dp就行了. 题干: 题目描述 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由N个连通的小村落组成,并且保证对于每两 ...
- 第九周 Leetcode 502. IPO (HARD)
Leetcode 502 一个公司 目前有资产W 可以选择实现K个项目,每个项目要求公司当前有一定的资产,且每个项目可以使公司的总资产增加一个非负数. 项目数50000 设计一个优先队列,对于当前状态 ...
- bzoj2521
最小生成树+最小割 ...我太zz了,没看出来全体减1是一个加1,看见后就是sb题了... 我们发现根据克鲁斯卡尔的过程,我们把边从小到大加入,如果两点已经相连就跳过,那么我们把所有小于等于这条边的边 ...
- 8. Ext文本输入框:Ext.form.TextField属性汇总
转自:https://blog.csdn.net/ryuudenne/article/details/8834650 Ext.form.TextField主要配置表: allowBlank ...
- bzoj 1655: [Usaco2006 Jan] Dollar Dayz 奶牛商店【高精度+完全背包】
居然要用高精度! 懒得operator了,转移是裸的完全背包 #include<iostream> #include<cstdio> using namespace std; ...
- SpringBoot集成MybatisPlus解决Mapper文件修改后动态刷新的问题
很多人在使用SpringBoot集成Mybatis或者MybatisPlus的时候在查询复杂的情况下会写mapper文件,虽然说MyBatisPlus提供了常用的增删查改,但还是难以应付复杂的查询.关 ...