C++继承的一般语法为:

class 派生类名:[继承方式] 基类名{
派生类新增加的成员
};

继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的)、private(私有的)和 protected(受保护的)。此项是可选的,如果不写,默认为 private 或 protected。

1) public继承方式

  • 基类中所有public成员在派生类中为public属性;
  • 基类中所有protected成员在派生类中为protected属性;
  • 基类中所有private成员在派生类中不可访问。

2) protected继承方式

  • 基类中的所有public成员在派生类中为protected属性;
  • 基类中的所有protected成员在派生类中为protected属性;
  • 基类中的所有private成员在派生类中仍然不可访问。

3) private继承方式

  • 基类中的所有public成员在派生类中均为private属性;
  • 基类中的所有protected成员在派生类中均为private属性;
  • 基类中的所有private成员在派生类中均不可访问。

由此可见:

  • 基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如,当继承方式为 protected 时,那么基类成员在派生类中的访问权限最高也为 protected,高于 protected 的会降级为 protected,但低于 protected 不会升级。
  • 基类中的 private 成员在派生类中始终是不可访问的。

private 继承限制太多,实际开发中很少使用,一般使用 public。

一个完整的例子:

#include<iostream>
using namespace std;
//基类--Pelple
class People{
private:
char *name;
int age;
public:
void setName(char*);
void setAge(int);
void display();
};
void People::setName(char *name){ this->name = name; }
void People::setAge(int age){ this->age = age; }
void People::display(){ cout<<name<<"的年龄是 "<<age; }
//派生类--Student
class Student: public People{
private:
float score;
public:
Student(char*, int, float);
void display1();
};
Student::Student(char *name, int age, float score){
this->setName(name);
this->setAge(age);
this->score = score;
}
void Student::display1(){
this->display();
cout<<",成绩是 "<<score<<endl;
}
int main(){
Student stu("小明", , 90.5);
stu.display1();
return ;
}

读者要注意 Student 类的构造函数和 display1() 函数。在构造函数中,我们要设置 name、age、score 变量的值,但 name、age 在基类中被声明为 private,所以在 Student 中不可直接访问,只能借助基类中的成员函数 setName()、setAge() 来间接访问。

在 display1() 函数中,同样不能访问 People 类中 private 属性的成员变量,只能借助 People 类的成员函数来间接访问。

改变访问属性

使用 using 关键字可以改变基类成员在派生类中的访问属性,例如将 public 改为 private,或将 private 改为 public。

using 关键字使用示例:

#include<iostream>
using namespace std;
class People{
protected:
char *name;
int age;
public:
void say();
};
void People::say(){
cout<<"你好,欢迎来到C语言中文网!"<<endl;
}
class Student: public People{
private:
using People::say; //改变访问属性
public:
using People::name; //改变访问属性
using People::age;
float score;
void learning();
};
void Student::learning(){
cout<<"我是"<<name<<",今年"<<age<<"岁,我学习非常努力,这次考了"<<score<<"分!"<<endl;
}
int main(){
Student stu;
stu.name = "小明";
stu.age = ;
stu.score = 99.5f;
stu.say(); //compile error
stu.learning();
return ;
}

代码中首先定义了基类 People,它包含两个 protected 属性的成员变量和一个 public 属性的成员函数。定义 Student 类时采用 public 继承方式,People 类中的成员在 Student 类中的访问权限默认是不变的。

不过,我们使用 using 改变了它们的默认访问权限,如代码第16~20行所示,将 say() 函数修改为 private 属性的,是降低访问权限,将 name、age 变量修改为 public 属性的,是提高访问权限。

多级继承

实际开发中,经常会有多级继承的情况。例如,类A为基类,类B继承自类A,类C又继承自类B,那么类C也是类A的派生类,它们构成了多级继承的关系。如下图所示:

多级继承的规则与上面相同,这里仅举例说明。

class A{  //基类
public:
int i;
protected:
void f2( );
int j;
private:
int k;
};
class B: public A{ //public继承
public:
void f3( );
protected:
void f4( );
private:
int m;
};
class C: protected B{ //protected方式
public:
void f5( );
private:
int n;
};

各成员在不同类中的访问属性如下:

  i f2 j k f3 f4 m f5 n
基类A 共有 保护 保护 私有          
共有派生类B 共有 保护 保护 不可访问 共有 保护 私有    
保护派生类C 保护 保护 保护 不可访问 保护 保护 不可访问 共有 私有

C++学习15 继承权限和继承方式的更多相关文章

  1. C++ 类中的3种访问权限和继承方式

    访问权限:public 可以被任意实体访问,protected 只允许子类(无论什么继承方式)及本类的成员函数访问,private 只允许本类的成员函数访问.三种继承方式分别是 public 继承,p ...

  2. 大数据学习--day10(继承-权限-super-final-多态-组合)

    继承-权限-super-final-多态-组合 权限修饰符     内容         public         protected         default(不写就是它)         ...

  3. Java(15)面向对象之继承

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201615.html 博客主页:https://www.cnblogs.com/testero ...

  4. 《Java核心技术·卷Ⅰ:基础知识(原版10》学习笔记 第5章 继承

    <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 目录 <Java核心技术·卷Ⅰ:基础知识(原版10>学习笔记 第5章 继承 5.1 类.超类和子类 5.1 ...

  5. JavaScript学习13 JavaScript中的继承

    JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...

  6. javascript实现继承的几种方式

    原型链方式实现继承 function SuperType(){ this.property = true; this.colors = ['red','blue','green']; } SuperT ...

  7. 转】Maven学习总结(五)——聚合与继承

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/4058008.html 感谢! 一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1. ...

  8. JavaScript高级特性-实现继承的七种方式

    声明和约定: 在C++和Java中,我们可以通过关键字class来声明一个类,在JavaScript中没有这个关键字,但我们知道可以通过new一个function创建对象,这个function类似C+ ...

  9. (转)Maven学习总结(五)——聚合与继承

    孤傲苍狼只为成功找方法,不为失败找借口! Maven学习总结(五)——聚合与继承 一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <mod ...

随机推荐

  1. easyUI之tabs

    js添加选项卡 $('#box').tabs('add',{option});add是一个方法 对于option来讲,它继承panel,具有它的所有属性.包括id,title,content等. 承前 ...

  2. 自动生成XML反序列化的类

    原文地址:http://www.cnblogs.com/jaxu/p/3632077.html   Visual Sutdio 2013增加了许多新功能,其中很多都直接提高了对代码编辑的便利性.如: ...

  3. 获取Asp.net GridView控件当中总的记录数量

    问题: 解决方案: SqlDataSource 或 AccessDataSource的selected事件的e.AffectedRows为查询操作返回的数据数目.(这个是在gridview分页情况下采 ...

  4. curl命令使用大全

    curl命令使用大全 可以看作命令行浏览器 1.开启gzip请求curl -I http://www.sina.com.cn/ -H Accept-Encoding:gzip,defalte 2.监控 ...

  5. 使用定时器实现JavaScript的延期执行或重复执行

    使用定时器实现JavaScript的延期执行或重复执行 window 对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和 window.setInterval.其中前 ...

  6. ASP.NET MV3 部署网站 报"Could not load file or assembly ' System.Web.Helpers “ 错的解决方法

    转自:http://www.cnblogs.com/taven/archive/2011/08/14/2138077.html 国内很多网站空间都只支持.NET 2.0 和 .NET 3.0 3.5, ...

  7. 06文件与IO

    这节主要学习系统调用stat.lstat.fstat. 格式如下: int fstat(int filedes, struct stat *buf); int stat(const char *pat ...

  8. 【jmeter】参数化User Defined Variables与User Parameters

    偶然发现JMeter中有两个元件(User Defined Variables与User Parameters)很相近,刚开始时我也没注意,两者有什么不同.使用时却发现两者使用场景有些不同,现在小结一 ...

  9. label 与 input

    <form onsubmit="return checkform()" > <div style=" width:100%; border:0px #0 ...

  10. bzoj4637: 期望

    Description 在米国有一所大学,名叫万国歌剧与信息大学(UniversalOperaandInformaticasUniversity).简称UOI大学.UO I大学的建筑与道路分布很有趣, ...