【c++】虚函数描写叙述符override

在C++11中为了帮助程序猿写继承结构复杂的类型,引入了虚函数描写叙述符override,假设派生类在虚函数声明时使用了override描写叙述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译。我们来看一下如代码清单2-25所看到的的这个简单的样例。

代码清单2-25

struct Base {

virtual void Turing() = 0;

virtual void Dijkstra() = 0;

virtual void VNeumann(int g) = 0;

virtual void DKnuth() const;

void Print();

};

struct DerivedMid: public Base {

// void VNeumann(double g);

// 接口被隔离了,曾想多一个版本号的VNeumann函数

};

struct DerivedTop : public DerivedMid {

void Turing() override;

void Dikjstra() override;           // 无法通过编译,拼写错误,并不是重载

void VNeumann(double g) override;   // 无法通过编译,參数不一致,并不是重载

void DKnuth() override;             // 无法通过编译,常量性不一致,并不是重载

void Print() override;              // 无法通过编译,非虚函数重载

};

// 编译选项:g++ -c -std=c++11 2-10-3.cpp

在代码清单2-25中,我们在基类Base中定义了一些virtual的函数(接口)以及一个非virtual的函数Print。其派生类DerivedMid中,基类的Base的接口都没有重载,只是通过凝视能够发现,DerivedMid的作者以前想要重载出一个“void VNeumann(double g)”的版本号。这行凝视显然迷惑了编写DerivedTop的程序猿,所以DerivedTop的作者在重载全部Base类的接口的时候,犯下了3种不同的错误:

函数名拼写错,Dijkstra误写作了Dikjstra。

函数原型不匹配,VNeumann函数的參数类型误做了double类型,而DKnuth的常量性在派生类中被取消了。

重写了非虚函数Print。

假设没有override修饰符,在代码清单2-25中,DerivedTop作者的4处能够编译过去 可是与他的愿意(想重载虚函数)有严重的偏差了 可是编译器不报错,继续编译下去 这样就难排查了。加上keywordoverride
这样编译器能够辅助检查是不是正确重载 。
假设没有override修饰符 DerivedTop的作者可能在编译后都没有意识到自己犯了这么多错误。由于编译器对以上3种错误不会有不论什么的警示。这里override修饰符则能够保证编译器辅助地做一些检查。我们能够看到,在代码清单2-25中,DerivedTop作者的4处错误都无法通过编译。

此外,值得指出的是,在C++中,假设一个派生类的编写者自觉得新写了一个接口,而实际上却重载了一个底层的接口(一些简单的名字如get、set、print就easy出现这种状况),出现这种情况编译器还是爱莫能助的。只是这样无意中的重载一般不会带来太大的问题,由于派生类的变量假设调用了该接口,除了可能存在的一些虚函数开销外,仍然会运行派生类的版本号。因此编译器也就没有必要提供检查“非重载”的状况。而检查“一定重载”的overridekeyword,对程序猿的实际应用则会更有意义。

还有值得注意的是,如我们在第1章中提到的,final/override也可以定义为正常变量名,仅仅有在其出如今函数后时才是可以控制继承/派生的keyword。通过这种设计,非常多含有final/override变量或者函数名的C++98代码就行被C++编译器编译通过了。但出于安全考虑,建议读者在C++11代码中应该尽可能地避免这种变量名称或将其定义在宏中,以防发生不必要的错误。

建议:假设派生类里面是像重载虚函数 就加上keywordoverride 这样编译器能够辅助检查是不是正确重载,假设没加这个keyword 也没什么严重的error 仅仅是少了编译器检查的安全性

【c++】虚函数描写叙述符override,布布扣,bubuko.com

时间: 2024-10-13 14:43:58

【c++】虚函数描写叙述符override的相关文章

openssl之BIO系列之12---文件描写叙述符(fd)类型BIO

文件描写叙述符(fd)类型BIO ---依据openssl doc\crypto\bio_s_fd.pod翻译和自己的理解写成 (作者:DragonKing [email protected] 公布于:httpgdwzh.126.com之openssl专 业论坛) 文件描写叙述符类型BIO也是一个source/sink型的BIO,它定义了下面一些类型的函数( openssl\bio.h): BIO_METHOD * BIO_s_fd(void); #define BIO_set_fd(b,fd,

每天进步一点点——Linux中的文件描写叙述符与打开文件之间的关系

转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆能够看成是文件,文件又可分为:普通文件.文件夹文件.链接文件和设备文件.文件描写叙述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引.其是一个非负整数(一般是小整数),用于指代被打开的文件.全部运行I/O操作的系统调用都通过文件描写叙述符.程序刚刚启动的时候.0是标准输入,1是标准输出,2是标准错误. 假设此

Linux 文件描写叙述符设置为非堵塞的方法

通过fcntl设置文件描写叙述符属性 fcntl即F_SETFL,F_GETFL的使用,设置文件的flags,堵塞设置成非堵塞,非堵塞设置成堵塞(这连个在server开发中能够封装为基本函数) 1.获取文件的flags,即open函数的第二个參数: flags = fcntl(fd,F_GETFL,0); 2.设置文件的flags: fcntl(fd,F_SETFL,flags); 3.添加文件的某个flags.比方文件是堵塞的,想设置成非堵塞: flags = fcntl(fd,F_GETFL

Python描写叙述符(descriptor)解密

Python中包括了很多内建的语言特性,它们使得代码简洁且易于理解.这些特性包括列表/集合/字典推导式,属性(property).以及装饰器(decorator).对于大部分特性来说,这些"中级"的语言特性有着完好的文档.而且易于学习. 可是这里有个例外,那就是描写叙述符. 至少对于我来说.描写叙述符是Python语言核心中困扰我时间最长的一个特性. 这里有几点原因例如以下: 有关描写叙述符的官方文档相当难懂,并且没有包括优秀的演示样例告诉你为什么须要编写描写叙述符(我得为Raymon

【c++】虚函数描述符override

在C++11中为了帮助程序员写继承结构复杂的类型,引入了虚函数描述符override,如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译.我们来看一下如代码清单2-25所示的这个简单的例子. 代码清单2-25 struct Base { virtual void Turing() = 0; virtual void Dijkstra() = 0; virtual void VNeumann(int g) = 0; virtual v

【OpenCV新手教程之十八】OpenCV仿射变换 & SURF特征点描写叙述合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 知乎:http://www.zhihu.com/people/mao-xing-yun 邮箱: [email protected] 写作当前博文时配套使用的OpenCV版本号: 2.4.9 本篇文章中.我们一起探讨了OpenCV

匹夫细说C#:从园友留言到动手实现C#虚函数机制

前言 上一篇文章匹夫通过CIL代码简析了一下C#函数调用的话题.虽然点击进来的童鞋并不如匹夫预料的那么多,但也还是有一些挺有质量的来自园友的回复.这不,就有一个园友提出了这样一个代码,这段代码如果被编译成CIL代码的话,对虚函数的调用会使用call而非callvirt: override string ToString() { return Base.ToString(); } 至于为何是这样,匹夫在回复中也做了解释,因为上面那段代码其实相当于是这样的: override string ToSt

你好,C++(37)上车的人请买票!6.3.3 用虚函数实现多态

6.3.3  用虚函数实现多态 在理解了面向对象的继承机制之后,我们知道了在大多数情况下派生类是基类的“一种”,就像“学生”是“人”类中的一种一样.既然“学生”是“人”的一种,那么在使用“人”这个概念的时候,这个“人”可以指的是“学生”,而“学生”也可以应用在“人”的场合.比如可以问“教室里有多少人”,实际上问的是“教室里有多少学生”.这种用基类指代派生类的关系反映到C++中,就是基类指针可以指向派生类的对象,而派生类的对象也可以当成基类对象使用.这样的解释对大家来说是不是很抽象呢?没关系,可以

OOP2(虚函数/抽象基类/访问控制与继承)

通常情况下,如果我们不适用某个函数,则无需为该函数提供定义.但我们必须为每个虚函数都提供定义而不管它是否被用到了,这因为连编译器也无法确定到底会适用哪个虚函数 对虚函数的调用可能在运行时才被解析: 当某个虚函数通过指针或引用调用时,编译器产生的代码直到运行时才能确定应该调用哪个版本的函数.被调用的函数是与之绑定到指针或引用上的对象的动态类型相匹配的那一个 注意:动态绑定只有当我们通过指针或引用调用虚函数时才会发生.当我们通过一个具有普通类型(非引用非指针)的表达式调用虚函数时,在编译时就会将调用