private是自己私有的,protected是可以让孩子知道的,public是公开的
三种访问权限
public:可以被任意实体访问,数据成员和函数成员可在成员函数,友元,继承类中直接使用。亦可以作为接口,供类的用户使用
protected:只允许子类及本类的成员函数访问,在基类中用法同private,在类外不能被基类对象访问。在派生类中,用法同基类的public,其成员在类内可被其继承类对象访问使用,类外一样不可以。
private:成员只能由类成员(类内)和友元访问。在类外不能被本类对象访问,不能被继承类访问(无论何种继承),虽然作为继承类的私有成员,但在使用过程中,是通过调用基类的构造函数完成参数的传递的。继承类不能访问基类的私有成员
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = ;
a2 = ;
a3 = ;
a = ;
}
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 = ; //正确
itema.a1 = ; //正确
itema.a2 = ; //错误,类外不能访问protected成员
itema.a3 = ; //错误,类外不能访问private成员
system("pause");
return ;
}
三种继承方式
public 继承
protect 继承
private 继承
组合结果
基类中 继承方式 子类中
public & public继承 => public
public & protected继承 => protected
public & private继承 = > private
protected & public继承 => protected
protected & protected继承 => protected
protected & private继承 = > private
private & public继承 => 子类无权访问
private & protected继承 => 子类无权访问
private & private继承 = > 子类无权访问
由以上组合结果可以看出
1、public继承不改变基类成员的访问权限
2、private继承使得基类所有成员在子类中的访问权限变为private
3、protected继承将基类中public成员变为子类的protected成员,其它成员的访问 权限不变。
4、基类中的private成员不受继承方式的影响,子类永远无权访问。
此外,在使用private继承时,还存在另外一种机制:准许访问 。
我们已经知道,在基类以private方式被继承时,其public和protected成员在子类中变为private成员。然而某些情况下,需要在子类中将一个或多个继承的成员恢复其在基类中的访问权限。
C++支持以两种方式实现该目的
方法一,使用using 语句,这是C++标准建议使用的方式
方法二,使用访问声明,形式为 base-class::member;, 位置在子类中适当的访问声明处。(注,只能恢复原有访问权限,而不能提高或降低访问权限)
为什么引入private,protected,public
1.类的一个特征就是封装,public和private作用就是实现这一目的。所以:用户代码(类外)可以访问public成员而不能访问private成员;private成员只能由类成员(类内)和友元访问。
2.类的另一个特征就是继承,protected的作用就是实现这一目的。所以:protected成员可以被派生类对象访问,不能被用户代码(类外)访问。
三种继承方式例子
public继承
#include<iostream>
#include<assert.h>
using namespace std; class A{
public:
int a;
A(){
a1 = ;
a2 = ;
a3 = ;
a = ;
}
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();
cout << b.a << endl;
cout << b.a1 << endl; //正确
cout << b.a2 << endl; //错误,类外不能访问protected成员
cout << b.a3 << endl; //错误,类外不能访问private成员
system("pause");
return ;
}
protected继承
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = ;
a2 = ;
a3 = ;
a = ;
}
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();
cout << b.a << endl; //正确。public成员
cout << b.a1 << endl; //错误,protected成员不能在类外访问。
cout << b.a2 << endl; //错误,protected成员不能在类外访问。
cout << b.a3 << endl; //错误,private成员不能在类外访问。
system("pause");
return ;
}
private继承
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
int a;
A(){
a1 = ;
a2 = ;
a3 = ;
a = ;
}
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();
cout << b.a << endl; //正确。public成员
cout << b.a1 << endl; //错误,private成员不能在类外访问。
cout << b.a2 << endl; //错误, private成员不能在类外访问。
cout << b.a3 << endl; //错误,private成员不能在类外访问。
system("pause");
return ;
}
派生类同名成员隐藏
派生类B中定义了和基类同名的成员a,此时基类的a仍然存在,可以验证
所以派生类包含了基类所有成员以及新增的成员,同名的成员被隐藏起来,调用的时候只会调用派生类中的成员。
如果要调用基类的同名成员,可以用以下方法:
记得这里是在类外访问,而a在基类中是public,所以继承方式应该为public,使得a在派生类中仍然为public,在类外可以访问。
再谈protected:protected成员访问权限详解
《C++ Primer》的时候,其中关于protected 成员的描述是这样的:
protected Members
The protected access label can be thought of as a blend of private and public :
Like private members, protected members are inaccessible to users of the class.
Like public members, the protected members are accessible to classes derived from this class.
In addition, protected has another important property:
A derived object may access the protected members of its base class only through a derived
object. The derived class has no special access to the protected members of base type objects.
在没有继承的情况下,protected跟private相同。在派生类的时候才出现分化。
上面那段英文前两条都很好理解,基类对象不能访问基类的protected成员,派生类中可以访问基类的protected成员。也就是说private成员是不能被继承的,只有public,protected的成员才可以被继承。
就是最后一条有些迷惑人,派生类对象如果要访问基类protected成员只有通过派生类对象,派生类不能访问基类对象的protected成员。
请注意 drived class和drived object:派生类和派生类对象。第一点和第二点都是针对派生类来说的。
对于第三点总结一句话:只有在派生类中才可以通过派生类对象访问基类的protected成员。
#include <iostream>
using namespace std;
class Base
{
public:
Base(){};
virtual ~Base(){};
protected:
int int_pro;
};
class A : public Base
{
public:
A(){};
A(int da){ int_pro = da; }
void Print(A &obj){ obj.int_pro = ; }
void PrintPro(){ cout << "The proteted data is " << int_pro << endl; }
};
int main()
{
A aObj;
A aObj2();
aObj2.PrintPro();
aObj.Print(aObj2);
aObj2.PrintPro(); //注释1
//aObj.int_pro = 8;
system("pause");
}
编译运行结果如下:
The protected data is 5
The protected data is 24
可见,在派生类内部直接访问protected成员和访问派生类对象基类的protected成员都是可行的。但是若果解开注释1.就会编译报错。
很多书上都说有派生类的情况下protected的访问权限同public。这种说法是不对的,类内部直接访问没什么区别,但是访问对象基类的protected成员只能是在该类的内部。
我这里只列举了只有一层继承的情况,如果有多重继承的情况,比如三层。那么。中间层的类的内部还可以访问第三层类对象的基类成员,但是不能访问第三层类自己的protected的成员
private是自己私有的,protected是可以让孩子知道的,public是公开的的更多相关文章
- python,关于这个里边的私有方法(private)、保护方法(protected)、公开方法(public)
__foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的. _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行 ...
- c++三种继承方式public,protect,private
C++中的三种继承public,protected,private 三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员 ...
- c++继承详解
C++中的三种继承public,protected,private 三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员 ...
- C++ 类中的3种权限作用范围
三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员函数访问 #include <iostream> #in ...
- JAVA常用关键字
Java 中常用关键字: 一一解释(先以印象注明含义,若有错误或未填写的待用到后补充.更新):(蓝色为不确定部分) abstract : 虚类 boolean : 类型定义——布尔型 break : ...
- PHP学习笔记 - 进阶篇(3)
PHP学习笔记 - 进阶篇(3) 类与面向对象 1.类和对象 类是面向对象程序设计的基本概念,通俗的理解类就是对现实中某一个种类的东西的抽象, 比如汽车可以抽象为一个类,汽车拥有名字.轮胎.速度.重量 ...
- php类的方法
方法就是在类中的function,很多时候我们分不清方法与函数有什么差别,在面向过程的程序设计中function叫做函数,在面向对象中function则被称之为方法. 同属性一样,类的方法也具有pub ...
- C#---------------继承和多态初步
继承:在程序中,如果一个类A:类B,这种机制就是继承. 子类可以继承父类的所有内容(成员)吗? 解析: 1.私有成员(属性和方法) 2.构造函数 3.final修饰过的方法,子类不能进行重写 3.访问 ...
- JavaSE:关键字(全)
访问控制: private 访问控制方式:私有的 protected 访问控制方式:受保护的 public 访问控制方式:公共的 类.方法和变量修饰符: abstract 声明抽象,表明类或者成员方法 ...
随机推荐
- HDU3666 差分约束
THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 小米路由器设置DMZ主机 并在外网访问
一.前提条件: 1.小米路由器 2.拥有公网IP的网络 二.步骤: 1.登陆小米路由器管理界面 miwifi.com 2.高级设置=>端口转发 页面底部的DMZ选项开启,然后选择需要映射到外 ...
- Web Api Action的筛选
web Api设置默认路由设置: 这种目标Action方法的选择有以下几轮: 1.针对 HTTP方法 进行筛选 2.针对参数类型,可以做参数约束 3.针对参数数量 另一种路由“api/{control ...
- js for等循环 跳出多层循环
js for 循环 跳出多层循环 ,,,,,,,]; // 8个数 ,,,,,,,]; //8个数 testFor(); console.log(') function testFor() { ;k& ...
- 不使用Tomcat,手写简单的web服务
背景: 公司使用的YDB提供了http的查询数据库服务,直接通过url传入sql语句查询数据-_-||.ydb的使用参照:https://www.cnblogs.com/hd-zg/p/7115112 ...
- 【51NOD-0】1134 最长递增子序列
[算法]动态规划 [题解]经典模型:最长上升子序列(n log n) #include<cstdio> #include<algorithm> #include<cstr ...
- 关于auto-keras训练cnn模型
# 我在训练自己的人脸分类模型的时候发现图片的维度不能太高,经过很多次测试过后觉得一般人脸图片分为28*28大小训练的效果比较好.建议在使用其训练自己的物体识别模型的时候,尽量把图片压缩到28*28# ...
- 抓起根本(二)(hdu 4554 叛逆的小明 hdu 1002 A + B Problem II,数字的转化(反转),大数的加法......)
数字的反转: 就是将数字倒着存下来而已.(*^__^*) 嘻嘻…… 大致思路:将数字一位一位取出来,存在一个数组里面,然后再将其变成数字,输出. 详见代码. while (a) //将每位数字取出来, ...
- 阅读关于DuReader:百度大规模的中文机器阅读理解数据集
很久之前就得到了百度机器阅读理解关于数据集的这篇文章,今天才进行总结!.... 论文地址:https://arxiv.org/abs/1711.05073 自然语言处理是人工智能皇冠上的明珠,而机器阅 ...
- AndroidStudio创建jinLibs文件夹
在文件中的buildTypes节点下添加 sourceSets.main { jniLibs.srcDir 'libs' } 如图