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

 更新时间:2023年06月14日 10:36:58   作者:洛克希德马丁  
本文主要介绍了C++11 上下文关键字的具体实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

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

一、关键字是什么?

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

二、使用步骤

1.简单例子

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

代码如下(示例):

#include <iostream>
int main(){
    int a = 0;
    float b = 1.0;
    double c = 2.0;
    return 0;
}

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

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

2.错误例子

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

代码如下(示例):

#include <iostream>
int main(){
    int int = 0;
    float float = 1.0;
    double double = 2.0;
    return 0;
}

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

#include <iostream>
int main(){
    int _int = 0;
    float _float = 1.0;
    double _double = 2.0;
    return 0;
}

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

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

三、特殊关键字

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

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

1.export关键字

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

2.override关键字

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

#include <iostream>
int main(){
    int override = 0;
    return 0;
}

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

请看下面的例子:

#include <iostream>
class X {
public:
    virtual void print() const;
};
void X::print() const {
    std::cout << "X::print()" << std::endl;
}
class Y : public X {
public:
    void print() const;
};
void Y::print() const {
    X::print();
    std::cout << "Y::print()" << std::endl;
}

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

请看完美写法:

#include <iostream>
class X {
public:
    virtual void print() const;
};
void X::print() const {
    std::cout << "X::print()" << std::endl;
}
class Y : public X {
public:
    void print() const override;
};
void Y::print() const {
    X::print(); //这个如果不需要可以去掉
    std::cout << "Y::print()" << std::endl;
}

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

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

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

3.final关键字

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

请看代码:

#include <iostream>
class X {
public:
    virtual void print() const;
    virtual void test() const final;
};
void X::print() const {
    std::cout << "X::print()" << std::endl;
}
void X::test() const {
    std::cout << "X::test()" << std::endl;
}
class Y : public X {
public:
    void print() const override;
    void test() const override;//这句编译不通过
};
void Y::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即可。

总结

到此这篇关于C++11 上下文关键字的具体实践的文章就介绍到这了,更多相关C++11 上下文关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c++字符串char[]数组分割split问题

    c++字符串char[]数组分割split问题

    这篇文章主要介绍了c++字符串char[]数组分割split问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • C语言算法练习之打鱼还是晒网

    C语言算法练习之打鱼还是晒网

    这篇文章主要该大家分享C语言打鱼还是晒网的练习,文章主要通过三天打鱼两天晒网的俗语提出问题,在某一天轮到打鱼还是晒网,下面来看详细内容吧,需要的朋友可以参考一下
    2022-03-03
  • socket多人聊天程序C语言版(二)

    socket多人聊天程序C语言版(二)

    这篇文章主要为大家详细介绍了socket多人聊天程序C语言版第二篇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • C语言栈与队列相互实现详解

    C语言栈与队列相互实现详解

    栈和队列,严格意义上来说,也属于线性表,因为它们也都用于存储逻辑关系为 "一对一" 的数据,但由于它们比较特殊,本章讲解分别用队列实现栈与用栈实现队列
    2022-04-04
  • C语言计算日期差的方法示例

    C语言计算日期差的方法示例

    这篇文章主要介绍了C语言计算日期差的方法,结合具体实例形式分析了C语言针对日期转换、运算等相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • C++中的vector使用详解及重要部分底层实现

    C++中的vector使用详解及重要部分底层实现

    本篇文章会对vector的语法使用进行详解,同时,还会对重要难点部分的底层实现进行讲解,其中有vector的迭代器失效和深拷贝问题,希望本篇文章的内容会对你有所帮助
    2023-07-07
  • C语言中for循环问题(一个小坑需注意)

    C语言中for循环问题(一个小坑需注意)

    这篇文章主要给大家介绍了关于C语言中for循环问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • C++重载运算符实现分数加减乘除

    C++重载运算符实现分数加减乘除

    这篇文章主要为大家详细介绍了C++重载运算符实现分数加减乘除,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C++11计时器之chrono库简介

    C++11计时器之chrono库简介

    C++11有了chrono库,可以在不同系统中很容易的实现定时功能,要使用chrono库,需要#include,其所有实现均在std::chrono namespace下,本文给大家介绍C++11计时器:chrono库介绍,感兴趣的朋友一起看看吧
    2023-12-12
  • c++智能指针的超详细讲解

    c++智能指针的超详细讲解

    c++程序设计中经常会用堆内存,程序员要自己管理内存的申请和释放,使用原始指针,容易造成堆内存泄漏(忘记释放),二次释放,使用智能指针能更好的管理堆内存,下面这篇文章主要给大家介绍了关于c++智能指针的相关资料,需要的朋友可以参考下
    2022-06-06

最新评论