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 声明抽象,表明类或者成员方法 ...
随机推荐
- train val test区别
train是训练集,val是训练过程中的测试集,是为了让你在边训练边看到训练的结果,及时判断学习状态.test就是训练模型结束后,用于评价模型结果的测试集.只有train就可以训练,val不是必须的, ...
- ACE线程管理机制-面向对象的线程类ACE_Task
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/05/583231.html 我们在前一章中使用ACE_Thread包装时,你一定已经注意到了一 ...
- UIView的autoresizingMask属性研究
在 UIView 中有一个autoresizingMask的属性,它对应的是一个枚举的值(如下),属性的意思就是自动调整子控件与父控件中间的位置,宽高. 1 2 3 4 5 6 7 8 9 enum ...
- HDU1573 线性同余方程(解的个数)
X问题 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- HDU1530 最大团 模板
Maximum Clique Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 轮廓算法的结果验证工具/How to validate the outline output
因为轮廓算法的结果通过直接观察输出很难判断结果的正确性. 但是如果把输入和输出同时绘制出来,用眼睛判别则相对简单许多. 输入建筑的文件内容格式为,粗体格式为建筑高度: 10 110 5020 60 7 ...
- JavaScript知识之判断字符串中出现最多的字符及次数
var str = 'asdddasdfdseeeeeweeeeeeeeeeeee'; var json = {}; // 定义json一个对象 for(var i = 0; i < str.l ...
- generatorConfiguration配置文件及其详细解读
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguratio ...
- 编辑器vi命令
代码: # vi + 文件名 //将光标放在文档最下面 进入编辑器后: i:插入 x:删除 w:保存 q:退出不保存 q!:强制退出不保存 wq:保存并退出
- Codeforces Round #411 (Div. 2) A-F
比赛时候切了A-E,fst了A Standings第一页只有三个人挂了A题,而我就是其中之一,真™开心啊蛤蛤蛤 A. Fake NP time limit per test 1 second memo ...