当前位置: 首页 > news >正文

C++11 上下文关键字的具体实践

前言

熟悉C++11的朋友都知道,C++有大概83个左右的关键字。

一、关键字是什么?

关键字(keyword)属于保留字,是整个语言范围内预先保留的标识符。每个C++关键字都有特殊的含义。经过预处理后,关键字从预处理记号(preprocessing-token)中区别出来,剩下的标识符作为记号(token),用于声明对象、函数、类型、命名空间等。不能声明与关键字同名的标识符

二、使用步骤

1.简单例子

这里举一些简单例子,比如定义变量使用的类型关键字:int,float,double这些。

代码如下(示例):

1

2

3

4

5

6

7

#include <iostream>

intmain(){

inta = 0;

floatb = 1.0;

doublec = 2.0;

return0;

}

这里main使用的是不带参数的版本。其他的关键字有各自的用法,由于C++语法体系比较复杂,只针对一些特殊的做说明。

像int这种内置类型不需要引用名字空间

2.错误例子

关键字是保留字,不能用来当变量名和函数名或者诸如名字空间名字、类名等等命名。说白了编译器正式通过解析关键字来理解语法结构,如果允许滥用关键字无疑会让编译器无法正常工作。

代码如下(示例):

1

2

3

4

5

6

7

#include <iostream>

intmain(){

intint= 0;

floatfloat= 1.0;

doubledouble= 2.0;

return0;

}

这里把int、float和double当作了普通变量名,IDE会报错提醒你,编译也无法通过。不过这并不意味着变量名中不能出现关键字的影子,请看下面的例子:

1

2

3

4

5

6

7

#include <iostream>

intmain(){

int_int = 0;

float_float = 1.0;

double_double = 2.0;

return0;

}

加了下划线的关键字就不是关键字了,就是普通变量了,可以正常编译。

注意:不要滥用双下划线,有些内置宏是以双下划线开头的。比如:__cplusplus,建议这种带关键字的变量名还是要少用或者不用,以免出现错误。

三、特殊关键字

终于还是到重头戏了,关键字本身的使用没什么好大书特书的,需要注意的上面已经说的够详细了。其他关键字的使用方法只要参考C++11的语法就行了。

接下来说几个特殊的“关键字”

1.export关键字

这个是C++11名副其实的关键字,只不过是个“未使用关键字”,暂时没有被赋予特殊的含义。但是,你仍然不能滥用它,比如:命名一个变量,还是和上面的所有关键字一样编译不通过。

2.override关键字

这个关键字比较特殊,它是用在“运行时多态”的“上下文关键字”。注意这个上下文关键字,它有特殊含义,而又跟其它关键字不太一样。你比如,最显著的差别就是它可以被用来命名变量,而且可以编译通过。

1

2

3

4

5

#include <iostream>

intmain(){

intoverride = 0;

return0;

}

可以编译通过,使用起来也没问题。这个是历史遗留问题,因为最早的时候还没有override这个关键字,之前的老代码中程序员大量使用这个命名变量,所以后来C++标准就把它定义为上下文关键字了。意思就是只有在特殊的场景下才有特殊含义,这个特殊含义就是“派生类复写基类的virtual方法”,这个override关键字甚至可以不用写,只不过IDE可能会给你个warning。

请看下面的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <iostream>

classX {

public:

virtualvoidprint()const;

};

voidX::print()const{

std::cout <<"X::print()"<< std::endl;

}

classY :publicX {

public:

voidprint()const;

};

voidY::print()const{

X::print();

std::cout <<"Y::print()"<< std::endl;

}

上面的写法就是不带override。但是,实际上是Y复写了X的print方法。建议不要这么写,加上override作为标识,让人一眼就能看出来这个方法是复写的基类方法!

请看完美写法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#include <iostream>

classX {

public:

virtualvoidprint()const;

};

voidX::print()const{

std::cout <<"X::print()"<< std::endl;

}

classY :publicX {

public:

voidprint()constoverride;

};

voidY::print()const{

X::print();//这个如果不需要可以去掉

std::cout <<"Y::print()"<< std::endl;

}

仔细观察能发现区别,const无论声明还是定义都是要加上的,override只需要在声明中加上,不需要再定义上加上,因为它“不是函数的一部分”。

重要的一点:override必须放在函数声明的最后位置,比如上面的例子,必须放在const后面。否则,编译无法通过。

我们今天不是来讨论运行时多态的用法的,所以更复杂的运行时多态本篇文章不讨论,我们只讨论“上下文关键字”和“保留关键字”之间的差别。

3.final关键字

用法和override不一样,不过同样可以作为一个变量名而被编译通过。
没错,final也是“上下文关键字”。final主要用在“阻止进一步派生”,看起来和override是相反的功能,其实不是这样的,无论有没有override这个关键字,派生行为都是现实存在的一种语法;而final恰巧能够阻止进一步派生。

请看代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

#include <iostream>

classX {

public:

virtualvoidprint()const;

virtualvoidtest()constfinal;

};

voidX::print()const{

std::cout <<"X::print()"<< std::endl;

}

voidX::test()const{

std::cout <<"X::test()"<< std::endl;

}

classY :publicX {

public:

voidprint()constoverride;

voidtest()constoverride;//这句编译不通过

};

voidY::print()const{

X::print();

std::cout <<"Y::print()"<< std::endl;

}

仍然是延续刚才的代码,print已经override了,我们不用管。X的test标记为final,在Y中尝试override就会报错,原因是test被标记为final。

这个时候你有两个选择:1就是将final去掉;2就是将Y的test代码去掉。两种选择都可以编译通过。

和override一样,final也是只出现在函数声明里,不会出现在函数定义里,要不然编译不通过。

特别说明:final不能修饰纯虚函数,因为纯虚函数必须被复写。

另外:virtual出现在函数声明的前面,overide出现在函数声明的后面,顺序不能搞错。如果virtual和overide在派生类的函数中同时出现,只需要保留override即可。如果override和final同时出现,只需要保留final即可。


http://www.jsqmd.com/news/709659/

相关文章:

  • 【VS Code Copilot Next 工作流自动化终极指南】:20年IDE专家亲授5大源码级配置技巧,错过再等一年?
  • 从双绞线到万兆光口:一篇看懂ethtool里‘Port’和‘Transceiver’背后的硬件选型门道
  • 2026年4月江苏办公/软体/酒店/中式家具全案交付能力成为实木家具厂商分水岭 - 2026年企业推荐榜
  • 聚焦多模态感知与 AI 融合 清华大数据智能讲堂共谋智能科技未来
  • 别再手动调表格宽度了!LaTeX中tabularx、adjustbox和tabular*三种方法实现页面同宽表格的保姆级对比
  • 2026年山东面粉加工设备与豆类磨粉机械采购指南 - 精选优质企业推荐官
  • 旷视校招 C++ 考试题到底怎么考
  • TouchGal:一站式Galgame社区平台终极指南与快速上手教程
  • 从Arduino到ESP32:深入理解IIC总线的‘线与’逻辑与开漏输出(附示波器实测波形)
  • 从‘地址荒’到‘路由瘦身’:CIDR如何成为互联网的隐形管家?
  • 小白程序员必看!一文理清网络安全与信息安全的差异关系
  • 2026年山东面粉加工设备、豆类加工设备与磨粉设备选购指南 - 精选优质企业推荐官
  • 简单视频下载助手:一键保存在线视频的终极指南
  • JPEGsnoop:终极JPEG图像深度解析与专业检测工具
  • 底子薄、语法乱也能冲雅思?天津超级学长真的适合基础薄弱考生吗 - 大喷菇123
  • 3个理由告诉你:为什么Element Plus是Vue 3开发者的必备UI组件库
  • HoVer-Net:如何用AI实现病理切片中的细胞核精准分割与分类?
  • 【GraphWorX32】【IDRA】项目迁移其他电脑后运行项目闪退
  • VS Code Copilot Next 工作流崩溃频发?紧急修复指南:定位src/agent/inference.ts第417行关键状态同步漏洞
  • 2026年山东面粉加工设备与豆类加工设备源头厂家选购指南 - 精选优质企业推荐官
  • 用Python实战卡方检验:从孟德尔豌豆到数据分布拟合(附完整代码)
  • 2026 园林造景石材哪家好:地产景观石、地产示范区景观石、售楼处景观石、中国黑景观石、太行金景观石、柏坡黄景石、驳岸石景墙干垒石墙石皮地铺石厂家口碑排行 - 海棠依旧大
  • 《重复率不是“最后改的”,是从第一秒就开始“管”的——好写作AI论文查重功能的真相拆解》
  • 康威生命游戏不止是算法:用C++和SFML打造一个带图形界面的模拟器
  • 抖音去水印批量下载:专业内容创作者的终极解决方案
  • 终极Windows优化指南:三步让老旧电脑重获新生
  • 2026 景观石材口碑优选指南:地产景观石、示范区售楼处景观石、中国黑景观石、太行金景观石、柏坡黄景石、干垒石墙、石皮地铺石厂家推荐 - 海棠依旧大
  • 【紧急预警】Python默认解释器正拖垮你的AI产品SLA:3种生产级替代方案(RustPython+Mojo+Nuitka AOT)实测对比
  • 从CAN总线到DoIP:为什么你的车载诊断工具需要理解UDS网络层(TP层)?
  • ASP.NET Core MVC深度解析:构建现代化Web应用的架构艺术