1.继承基础:

    继承就像是生物里的遗传与变异,即派生类(子代)从基类(父代)那里继承基类的某些特性(遗传),并在此基础上拥有自己的特性(变异)。

    C++派生语法:

    class Base//定义一个基类

    {

      //...基类成员

    };

    class Derived:access-specifier Base//定义一个派生类

    {

      //...派生类成员

    }

    其中access-specifier可以是public、private、protected(表示派生类有一个基类)。

    以下程序清单从Fish类派生出了Carp和Tuna类的一种简单的继承层次结构:

#include<iostream>
using namespace std;
class Fish //定义Fish类
{
public:
bool FreshWaterFish; void Swim()
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
}
}; class Tuna :public Fish//定义Tuna类,将继承的Fish类的成员或方法作为自己的public成员或方法
{
public:
Tuna()
{
FreshWaterFish = false;
}
}; class Carp :public Fish
{
public:
Carp()
{
FreshWaterFish = true;
}
}; int main()
{
Carp myLunch;
Tuna myDinner; cout << "Getting my food to swim" << endl; cout << "Lunch:";
myLunch.Swim(); cout << "Dinner:";
myDinner.Swim(); return ;
}

 2.向基类传递参数:

    向基类传递参数在初始化派生类对象时有的时候显得很有用。比如上面的Fish类派生出Carp类和Tuna类,可以修改成如下代码:

#include<iostream>
using namespace std;
class Fish
{
protected:
bool FreshWaterFish;
Fish(bool IsFreshWater)
{
FreshWaterFish = IsFreshWater;
}
public:
void Swim()
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
return;
}
}; class Tuna :public Fish
{
public:
Tuna():Fish(false) {}//派生类每次定义对象都指出是淡水鱼还是咸水鱼,采用参数列表将bool值传递给基类的构造函数
}; class Carp :public Fish
{
public:
Carp():Fish(true) {}
}; int main()
{
Carp myLunch;
Tuna myDinner; cout << "Getting my food to swim" << endl; cout << "Lunch:";
myLunch.Swim(); cout << "Dinner:";
myDinner.Swim(); return ;
}

  3.在派生类中覆盖基类的方法:

    如果派生类中有和基类中的函数名相同,返回值和特征标也相同时,就相当于派生类的方法覆盖了基类的方法。我们还拿Fish类,Tuna类和Carp类来举例子。

    用Tuna和Carp类的Swim()覆盖Fish类的Swim():

    

#include<iostream>
using namespace std;
class Fish
{
protected:
bool FreshWaterFish;
Fish(bool IsFreshWater)
{
FreshWaterFish = IsFreshWater;
}
public:
void Swim()
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
return;
}
}; class Tuna :public Fish
{
public:
Tuna():Fish(false) {}
void Swim()//此函数与基类函数在调用上效果相同,基类函数被覆盖
{
cout << "Tuna swim fast" << endl;
}
}; class Carp :public Fish
{
public:
Carp():Fish(true) {}
void Swim()
{
cout << "Carp swim low" << endl;
}
}; int main()
{
Carp myLunch;
Tuna myDinner; cout << "Getting my food to swim" << endl; cout << "Lunch:";
myLunch.Swim(); cout << "Dinner:";
myDinner.Swim(); return ;
}

    上面的程序的结果显示了,在主函数中对象调用方法Swim()时调用的并不是Fish类里的方法了,而是Tuna和Carp自己的方法,这样基类的方法就相当于是被覆盖了。覆盖是的派生类的方法可以自定    义,但如果我们还想使用基类的方法,就必须想办法使得机器可以知道我们调用的Swim()的作用域在哪个范围。

 4. 调用基类中被覆盖的方法:

    上面说到了我们只需要让机器知道我们调用的Swim()的作用域,就可以使得被覆盖的基类方法重新被调用。我们可以在调用基类方法时使用"::"作用域解析运算符。

    以上面的调用Swim()的代码为例:

    myLunch.Swim();//调用派生类Carp中的Swim()

    my.Lunch.Fish::Swim();//调用基类Fish中的Swim()

    如果基类的方法没有被覆盖,则可以在派生类中和调用函数一样来调用基类的方法。如果被覆盖的话就要使用"::"作用域解析运算符。在主函数里调用就是类似语句:"my.Lunch.Fish::Swim();"在派   生类调用基类被覆盖方法时类似于语句:"Fish::Swim"。

  5. 在派生类中隐藏基类的方法:

    覆盖的一种极端情形就是,Tuna::Swim()可能隐藏Fish::Swim()的所有重载版本,使得使用这些重载版本会导致编译错误。

    以下面代码为例:

  

 #include<iostream>
using namespace std;
class Fish
{
public:
void Swim()
{
cout << "Fish swims...!" << endl;
}
void Swim(bool FreshWaterFish)
{
if (FreshWaterFish)
cout << "Swims in lake" << endl;
else
cout << "Swims in sea" << endl;
return;
}
}; class Tuna :public Fish
{
public:
void Swim()
{
cout << "Tuna swim fast" << endl;
}
};
int main()
{
Tuna myDinner; cout << "Getting my food to swim" << endl;
cout << "Dinner:";
myDinner.Swim();
//myDinner.Swim(false); return ;
}

    代码在6-17行实现了基类方法Swim的重载,在23-26行实现了派生类方法Swim对基类方法Swim的覆盖。观察发现派生类里只有一个版本的Swim方法,Fish中的Swim的重载版本Swim(bool)版本好像是没   有被覆盖,但其实Swim(bool)也类似被覆盖的情况是没法在派生类或主函数中像调用其他函数那样被调用的。如果我们去掉35行的注释符号,代码就会有编译错误,这也说明了问题。以上说明了在派生类   中覆盖基类的方法时是与函数的参数无关的,只要函数名称,返回值,特征值相同就会被覆盖。

    调用基类中被隐藏的方法:

    解决方案1:在main函数中使用作用域解析运算符"::"。

    myDinner.Fish::Swim();

    解决方案2:在派生类中使用关键字using解除对基类方法的隐藏。

    class Tuna:public Fish

    {

    public:

      using Fish Swim;//解除对Fish::Swim()重载版本的隐藏,其中不包括与派生类参数也相同的方法。

      void Swim(){}

    }

    解决方案3:在Tuna类中重新定义所有Fish类的被覆盖的方法的重载版本。

C++学习 之 继承(笔记)的更多相关文章

  1. Python学习的个人笔记(基础语法)

    Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...

  2. hadoop2.5.2学习及实践笔记(四)—— namenode启动过程源码概览

    对namenode启动时的相关操作及相关类有一个大体了解,后续深入研究时,再对本文进行补充 >实现类 HDFS启动脚本为$HADOOP_HOME/sbin/start-dfs.sh,查看star ...

  3. hadoop2.5.2学习及实践笔记(二)—— 编译源代码及导入源码至eclipse

    生产环境中hadoop一般会选择64位版本,官方下载的hadoop安装包中的native库是32位的,因此运行64位版本时,需要自己编译64位的native库,并替换掉自带native库. 源码包下的 ...

  4. 开始记录学习java的笔记

    今天开始记录学习java的笔记,加油

  5. 菜鸟教程之学习Shell script笔记(上)

    菜鸟教程之学习Shell script笔记 以下内容是,学习菜鸟shell教程整理的笔记 菜鸟教程之shell教程:http://www.runoob.com/linux/linux-shell.ht ...

  6. Exception类的学习与继承总结

    日期:2018.11.11 星期日 博客期:023 Exception类的学习与继承总结 说起来我们上课还是说过的!老师提到了报错问题出现主要分Exception和Error两类!第一次遇见这个问题是 ...

  7. 深度学习Keras框架笔记之AutoEncoder类

    深度学习Keras框架笔记之AutoEncoder类使用笔记 keras.layers.core.AutoEncoder(encoder, decoder,output_reconstruction= ...

  8. 深度学习Keras框架笔记之TimeDistributedDense类

    深度学习Keras框架笔记之TimeDistributedDense类使用方法笔记 例: keras.layers.core.TimeDistributedDense(output_dim,init= ...

  9. 深度学习Keras框架笔记之Dense类(标准的一维全连接层)

    深度学习Keras框架笔记之Dense类(标准的一维全连接层) 例: keras.layers.core.Dense(output_dim,init='glorot_uniform', activat ...

  10. Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation

    原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

随机推荐

  1. Liblinear Visual studio 2013 Error C3057

    使用LibLinear时编译时出现Error C3057的错误: OpenMP报错,查询MSDN: #pragma omp threadprivate(var)//var在编译之前必须是确定值 所以修 ...

  2. 前端 Jenkins 自动化部署

    这两天折腾了一下 Jenkins 持续集成,由于公司使用自己搭建的 svn 服务器来进行代码管理,因此这里 Jenkins 是针对 svn 服务器来进行的配置,Git 配置基本一致,后面也介绍了下针对 ...

  3. 2018-2019-2 网络对抗技术 20165205 Exp8 Web基础

    2018-2019-2 网络对抗技术 20165205 Exp8 Web基础 1.原理与实践说明 1.1实践内容 Web前段HTML:能正常安装.启停Apache.理解HTML,理解表单,理解GET与 ...

  4. Nginx-rtmp之 AMF0 的处理

    1. 综述 当检测到接收到的 RTMP 消息中 Message Header 中 message type id 为 20 时,表示,接收到的是 AMF 类型的数据, 因此需要对接收的数据进行 AMF ...

  5. Constructor、Method、Field 源码阅读

    AnnotatedElement /** * AnnotatedElement 接口表示目前正在此 VM 中运行的应用程序的一个已注解元素[类.方法.属性]. * 该接口允许反射性地读取注解.此接口中 ...

  6. Cortex-M3 异常中断响应与返回

    [异常/中断响应]Cortex-M3的异常/中断响应序列包括: 入栈:把8个寄存器的值压入栈. 取向量:从向量表中找出对应的服务程序入口地址. 更新寄存器:更新堆栈指针SP,更新连接寄存器LR,更新程 ...

  7. 基于redis的高并发秒杀的JAVA-DEMO实现!

    在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能.假设我们通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EX ...

  8. python解压压缩包

    默认解压到当前目录 import shutil shutil.unpack_archive('/root/redis-3.2.3.tar.gz') 解压到home目录下 import shutil s ...

  9. Autofac实现AOP拦截

    本文主要是详解一下在ASP.NET Core中,采用替换后的Autofac来实现AOP拦截. Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题.AO ...

  10. 2019年大牛最新整理的Python技术入门路线

    Python作为一门学习上手快.开发效率高.代码优雅的编程语言,一直以来都是最热门的几种语言之一,甚至在进入2019年之后热度超过了十几年的霸主Java,成为最受欢迎的语言.Python一直有胶水语言 ...