C++中Override

C++11中override关键字使用 什么是override? override 是C++11引进的一个说明符,翻译为 覆盖 的意思。C++11 中的 override 关键字,可以显式的在派生类中声明,哪些成员函数需要被重写,如果没被重写,则编译器会报错。 override有什么用? 在我们C++编程过程中,最熟悉的就是对接口方法的实现,在接口中一般只是对方法进行了声明(declaration),而我们在实现时,就需要实现接口声明的所有方法。 在程序中加override 关键字,可以避免派生类中忘记重写虚函数的错误。 另一个典型.. 阅读详情

1  公有继承

  公有继承包含两部分:一是 "接口" (interface),二是 "实现" (implementation)

  基类 Shape 中,三个成员函数,代表三种继承方式:

复制代码
class Shape {
public:
    virtual void Draw() const = 0;    // 1) 纯虚函数
    virtual void Error(const std::string& msg);  // 2) 普通虚函数
    int ObjectID() const;  // 3) 非虚函数
};

class Rectangle: public Shape { ... };
class Ellipse: public Shape { ... };
复制代码

1.1  纯虚函数 (pure virtual)

  纯虚函数,表示继承的只是基类成员函数的接口,且要在派生类中重写该函数的实现

Shape *ps1 = new Rectangle;
ps1->Draw(); // calls Rectangle::Draw

Shape *ps2 = new Ellipse;
ps2->Draw(); // calls Ellipse::Draw

  若想调用基类的 Draw(),须加上 类作用域操作符 ::

ps1->Shape::Draw(); // calls Shape::draw

1.2  普通虚函数

  普通虚函数,对应在基类中定义一个缺省的实现 (default implementation),表示继承的是基类成员函数的接口和缺省的实现,由派生类自行选择是否重写该函数。

  实际上,允许普通虚函数同时继承接口和缺省实现是危险的。 如下, ModelA 和 ModelB 是 Airplane 的两种飞机类型,且二者的飞行方式完全相同

class Airplane {
public:
    virtual void Fly(const Airport& destination);
};
class ModelA: public Airplane { ... };
class ModelB: public Airplane { ... };

  这是典型的面向对象设计,两个类共享一个特性 -- Fly,则 Fly 可在基类中实现,并由两个派生类继承之

  现增加一个新的飞机型号 ModelC,其飞行方式与 ModelA,ModelB 并不相同,假如不小心忘了在 ModelC 中重写新的 Fly 函数

class ModelC: public Airplane {
    ... // no fly function is declared
};

  则调用 ModelC 中的 fly 函数,就是调用 Airplane::Fly,但是 ModelC 的飞行方式和缺省的并不相同

Airplane *pa = new ModelC;
pa->Fly(Qingdao); // calls Airplane::fly!

  这就是前面所说的,普通虚函数同时继承接口和缺省实现是危险的,最好是基类中实现缺省行为 (behavior),但只有在派生类要求时才提供该缺省行为

1.2.1  解决方法一 

  一种方法是 纯虚函数 + 缺省实现,因为是纯虚函数,所以只有接口被继承,其缺省的实现不会被继承。派生类要想使用该缺省的实现,必须显式的调用

复制代码
class Airplane {
public:
    virtual void Fly(const Airport& destination) = 0;
};

void Airplane::Fly(const Airport& destination)
{ 
    // a pure virtual function default code for flying an airplane to the given destination
}

class ModelA: public Airplane {
public:
    virtual void Fly(const Airport& destination) { Airplane::Fly(destination); }
};
复制代码

  这样在派生类 ModelC 中,即使一不小心忘记重写 Fly 函数,也不会调用 Airplane 的缺省实现

复制代码
class ModelC: public Airplane {
public:
    virtual void Fly(const Airport& destination);
};

void ModelC::Fly(const Airport& destination)
{
    // code for flying a ModelC airplane to the given destination
}
复制代码

1.2.2  解决方法二 

  可以看到,上面问题的关键就在于,一不小心在派生类 ModelC 中忘记重写 fly 函数,C++11 中使用关键字 override,可以避免这样的“一不小心”

1.3  非虚函数

  非虚成员函数没有 virtual 关键字,表示派生类不但继承了接口,而且继承了一个强制实现 (mandatory implementation)

  既然继承了一个强制的实现,则在派生类中,无须重新定义 (redefine) 继承自基类的成员函数,如下:

  使用指针调用 ObjectID 函数,则都是调用的 Shape::ObjectID()

复制代码
Rectangel rc; // rc is an object of type Rectangle

Shape *pB = &rc; // get pointer to rc
pB->ObjectID(); // call ObjectID() through pointer

Rectangle *pD = &rc; // get pointer to rc
pD->ObjectID(); // call ObjectID() through pointer
复制代码

  如果在派生类中重新定义了继承自基类的成员函数 ObjectID 呢?

复制代码
class Rectangel : public Shape {
public:
    int ObjectID() const; // hides Shape::ObjectID
};

pB->ObjectID(); // calls Shape::ObjectID()
pD->ObjectID(); // calls Rectagle::ObjectID()
复制代码

  此时,派生类中重新定义的成员函数会 “隐藏” (hide) 继承自基类的成员函数

  这是因为非虚函数是 “静态绑定” 的,pB 被声明的是 Shape* 类型的指针,则通过 pB 调用的非虚函数都是基类中的,既使 pB 指向的是派生类

  与“静态绑定”相对的是虚函数的“动态绑定”,即无论 pB 被声明为 Shape* 还是 Rectangle* 类型,其调用的虚函数取决于 pB 实际指向的对象类型

 

2  重写 (override)

  在 1.2.2 中提到 override 关键字,可以避免派生类中忘记重写虚函数的错误

  下面以重写虚函数时,容易犯的四个错误为例,详细阐述之

复制代码
class Base {
public:
    virtual void mf1() const;
    virtual void mf2(int x);
    virtual void mf3() &;
    void mf4() const;    // is not declared virtual in Base
};

class Derived: public Base {
public:
    virtual void mf1();        // declared const in Base, but not in Derived.
    virtual void mf2(unsigned int x);    // takes an int in Base, but an unsigned int in Derived
    virtual void mf3() &&;    // is lvalue-qualified in Base, but rvalue-qualified in Derived.
    void mf4() const;        
};
复制代码

  在派生类中,重写 (override) 继承自基类成员函数的实现 (implementation) 时,要满足如下条件:

  一虚:基类中,成员函数声明为虚拟的 (virtual)

  二容:基类和派生类中,成员函数的返回类型和异常规格 (exception specification) 必须兼容

  四同:基类和派生类中,成员函数名、形参类型、常量属性 (constness) 和 引用限定符 (reference qualifier) 必须完全相同

  如此多的限制条件,导致了虚函数重写如上述代码,极容易因为一个不小心而出错

  C++11 中的 override 关键字,可以显式的在派生类中声明,哪些成员函数需要被重写,如果没被重写,则编译器会报错。

复制代码
class Derived: public Base {
public:
    virtual void mf1() override;
    virtual void mf2(unsigned int x) override;
    virtual void mf3() && override;
    virtual void mf4() const override;
};
复制代码

  这样,即使不小心漏写了虚函数重写的某个苛刻条件,也可以通过编译器的报错,快速改正错误

复制代码
class Derived: public Base {
public:
    virtual void mf1() const override;  // adding "virtual" is OK, but not necessary
    virtual void mf2(int x) override;
    void mf3() & override;
    void mf4() const override; 
}; 
复制代码

 

小结:

1)  公有继承

  纯虚函数      => 继承的是:接口 (interface)

  普通虚函数   => 继承的是:接口 + 缺省实现 (default implementation)

  非虚成员函数 =>继承的是:接口 + 强制实现 (mandatory implementation)

2)  不要重新定义一个继承自基类的非虚函数 (never redefine an inherited non-virtual function)

3)  在声明需要重写的函数后,加关键字 override

 

参考资料:

 <Effective C++_3rd> item 34, item 36

 <Effective Modern C++> item 12

 

【C++11保姆级教程】final和override 在C++编程中,我们常常需要使用继承和多态来构建复杂的程序。然而,在继承关系中,有时候我们需要对继承层次做出一些限制,确保某些类或函数不能再被继承或重写。为了解决这个问题,C++11引入了两个关键字,分别是final和override。本篇教程将向大家介绍final和override的具体用法,帮助大家更好地理解和应用这两个关键字。final和override关键字在C++中提供了对类继承和函数重写行为的额外控制。 阅读详情

相关推荐

MATLAB 论文复现——基于虚拟储能的电动汽车充放电调度策略及激励评价

文章基于虚拟储能聚合体仿真模型优化电动汽车充放电调度,并采用复合权重评价电动汽车的充电激励。根据电动汽车灵活性和系统稳定性衡量其贡献大小,并通过模糊推理系统模拟用户的充电意愿,实现对电动汽车充电的引导和优化。[1]陈朔,胡昊,方慧敏,等.基于虚拟储能的电动汽车充放电调度策略及激励评价[J/OL].系统仿真学报,1-12[2024-07-24].https://doi.org/10.16182/j.issn1004731x.joss.23-1316.基于虚拟储能的电动汽车充放电调度策略及激励评价。

sjr1478的博客 363

C++11 之 override

1 公有继承 公有继承包含两部分:一是"函数接口" (interface),二是"函数实现" (implementation) 如 Shape 类中,三个成员函数,表示三种继承方式: class Shape { public: virtual void Draw() const = 0; // 1) 纯虚函数 virtual void Error...

weixin_30527323的博客 616

【计算机视觉40例】案例08:石头剪刀布手势识别

计算机视觉40例——从入门到深度学习(OpenCV-Python)》在介绍Python基础、OpenCV基础、计算机视觉理论基础、深度学习理论的基础上,介绍了计算机视觉领域内具有代表性的40个典型案例。这些案例中,既有传统的案例(数字识别、答题卡识别、物体计数、缺陷检测、手势识别、隐身术、以图搜图、车牌识别、图像加密、指纹识别等),也有深度学习案例(图像分类、风格迁移、姿势识别、实例分割等),还有人脸识别方面的案例(表情识别、驾驶员疲劳监测、识别性别与年龄等)。......

计算机视觉之光 2155

【Note】C++ 函数后加 const override 的用法

1. const 用法 const加在函数前表示函数返回值为const,加在函数后表示不可修改class的成员变量。 const加在函数后面表示此函数“只读”。 2. override用法 override关键字表示重写父类的虚函数。 1. 表示重写了父类的函数增加可读性 2. 编译器会检查重写的函数与父类的虚函数是否一致 Example: class Base { public: virtual void Test(int number) const; }; class Oba

qq_35516517的博客 1万+

【RS】哨兵系列数据下载(哨兵2号Sentinel-2波段介绍、下载)

以哨兵二号为示例,分享如何下载欧空局的哨兵系列数据

Remote Sensing迷途小书童 1万+

YOLOv12改进策略【损失函数篇】| 替换Powerful-IoU(PIoU),增强对中等质量锚框的关注力,引导锚框更直接、高效地回归

本文针对现有基于IoU的损失函数在目标检测任务中存在的问题,提出了利用Powerful-IoU(PIoU)及其升级版PIoU v2改进YOLOv12的损失函数,以提高模型精度。文章详细介绍了PIoU和PIoU v2的结构原理,并提供了在YOLOv12中实现这些损失函数的具体步骤和代码修改方法。

Limiiiing的博客 931

c++中 override用法

描述:override保留字表示当前函数重写了基类的虚函数。 目的: 1.在函数比较多的情况下可以提示读者某个函数重写了基类虚函数(表示这个虚函数是从基类继承,不是派生类自己定义的); 2.强制编译器检查某个函数是否重写基类虚函数,如果没有则报错。 用法:在类的成员函数参数列表后面添加该关键字既可。 例子: class Base { virtual void f(); }; class Deriv...

qq_43026520的博客 7270

Qt C++ 电子海图与作战叠加(Overlay)系统

lab_pos->setText(QString("坐标: X%1 Y%2").arg(p.x(),0,'f',0).arg(p.y(),0,'f',0));lab_distance->setText(QString("距离: %1 海里").arg(dist,0,'f',1));lab_bearing->setText(QString("方位: %1°").arg(bear,0,'f',1));// 绘制S-57海图基底。scene->addText("封锁线").setPos(450,180);

寒寒豆豆软件公司的博客 495

C++之override

C++ 之 override 作用 不使用override 使用override 作用 在成员函数声明或定义中, override 确保该函数为虚函数并覆写来自基类的虚函数。 位置:函数调用运算符之后,函数体或纯虚函数标识 “= 0” 之前。 不使用override #include "pch.h" #include <iostream> using namespace ...

枫影竹韵的博客 1756

git clone出现fatal: unable to access Failed to connect to github.com port 443: Timed out解决方案

本文主要介绍了git clone出现fatal: unable to access Failed to connect to github.com port 443: Timed out解决方案,希望能对使用git的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 23万+

Android实现自动输入文本效果 (附完整源码)

Android实现自动输入文本效果 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 413

C++ 关于override关键字使用详解

因此,只要函数签名相同,派生类的函数就可以覆盖基类的函数,无论这两个函数的实现是否相同。这就是前面所说的,普通虚函数同时继承接口和缺省实现是危险的,最好是基类中实现缺省行为 (behavior),但只有在派生类要求时才提供该缺省行为.一种方法是 纯虚函数 + 缺省实现,因为是纯虚函数,所以只有接口被继承,其缺省的实现不会被继承。这是因为非虚函数是 “静态绑定” 的,p1被声明的是 Person* 类型的指针,则通过 p1调用的非虚函数都是基类中的,既使 指向的是派生类。

nihao_2014的博客 1万+

一键生成Microsoft Store应用直链下载:绕过商店故障的终极方案

遇到商店无法加载时,复制链接 → 粘贴到Adguard → 下载主程序包 → 开启开发者模式安装。整个过程耗时不超过2分钟,彻底摆脱商店依赖!

安德洛夫 2179

C++ 中提供的override 关键字

C++ 语言标准这些年进化的很快,许多新引入的特性我都没有用过。说实话自己也比较懒,总是觉得自己对C++ 的掌握程度已经足够应付日常的各种项目了,所以没有学习新特性的动力。而且一直觉得新引入的特性多数都属于那种“语法糖”,能够发挥的作用不大,其实是可有可无的。 不过最近编写一个小程序时代码里有个小bug,困扰了我好几天。最后在几个热心网友的帮助下才解决了。这个小bug让我认识到C++11 中提供

Ivan 的专栏 4万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++11 override

C++11 之 override作用不使用override使用override 作用 在成员函数声明或定义中, override 确保该函数为虚函数并覆写来自基类的虚函数。 位置:函数调用运算符之后,函数体或纯虚函数标识 “= 0” 之前。 不使用override #include &amp;lt;iostream&amp;gt; using namespace std; class Base { public...

wuj的专栏 2万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++练习之override操作

C++中override(覆盖)操作符是类封装中应用到最基本的操作,琢磨了下,才算是懂了点点,以下是自己的一些理解,如有不对之处,请指正,谢谢! 源码下载地址:git clone https://laneyu@bitbucket.org/laneyu/cplusplus.git sample目录下既是本文所有例子测试代码 一、operator+操作 operator+操作主要有四种方式:

coderlang 1703

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

c++的virtual和override作用

一、概述 c++的virtual提供了运行时的多态,是的可以用基类的指针调用子类对象的函数,通过override可以强制要求基类有对应的虚函数。 二、测试代码 #pragma once #include <stdio.h> class Base { public: void A_1() { printf("Base::A_1\n"); }; virtual void A...

游戏猫的博客 6954

C++ 中override的作用

描述:override保留字表示当前函数重写了基类的虚函数。 目的:1.在函数比较多的情况下可以提示读者某个函数重写了基类虚函数(表示这个虚函数是从基类继承,不是派生类自己定义的);2.强制编译器检查某个函数是否重写基类虚函数,如果没有则报错。 用法:在类的成员函数参数列表后面添加该关键字既可。 例子: class Base { virtual void f(); };

qq_33485434的博客 6万+

C++ override 关键字用法

override关键字作用: 如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译。 举例子说明struct Base { virtual void Turing() = 0; virtual void Dijkstra() = 0; virtual void VNeumann(int g) = 0;

小黑霸气 的专栏 11万+

C++中override关键字

本文转自:https://blog.youkuaiyun.com/xiaoheibaqi/article/details/51272009 override关键字作用: 如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译。 举例子说明 struct Base { virtual void Turing() = 0; ...

qq_16334327的博客 895

C++ 继承之Override

C++继承之Override1.共有继承1.1纯虚函数1.2普通虚函数1.2.1 方法一1.2.2方法二1.3非虚函数2.重写(override)3.小结 1.共有继承 公有继承包含两部分:一是 “函数接口” (interface),二是 “函数实现” (implementation) 如 Shape 类中,三个成员函数,表示三种继承方式: class Shape { public: vi...

language_zcx的博客 2240

C++-[override]关键字使用详解

本文介绍了C++ override关键字使用详解以及与重载的区别。

沐槿的博客 5万+

【C++关键字 override】

如果派生类重载了基类中的同名函数,则该函数将成为派生类中的虚函数,可以通过调用基类中的函数来实现该函数的功能。因此,在C++中,override关键字是非常重要的一个特性,对于实现灵活的类型重载和抽象函数的使用非常有帮助。这可能会导致一些错误,例如如果派生类中的函数签名与基类中的虚函数不完全匹配,那么这个函数可能不会被视为重写,而编译器也不会报错。它可以帮助程序员避免一些常见的错误,例如误打误写导致的函数签名不匹配,以及在基类中添加或修改虚函数时忘记更新派生类中的函数等。

zwh1298454060的博客 752

C++中virtual和override的作用

C++中virtual和override的作用 C++的virtual提供了运行时的多态(后绑定),可以用基类的指针调用子类对象的函数。 通过override可以强制要求基类有对应的虚函数。 使用原则 基类函数没加virtual,子类有相同函数,实现的是覆盖。用基类指针调用时,调用到的是基类的函数;用子类指针调用时,调用到的是子类的函数。 基类函数加了virtual时,实现的时重写。用基类指针或子类指针调用时,调用到的都是子类的函数。 函数加上override,强制要求基本相同函数需要是虚函数,否

quietbxj的博客 6872
上一篇: C++11特性之override和final关键字
下一篇: C++中static、const、static const修饰变量作用详解
imJaron
博客等级 码龄11年 121粉丝 286原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值