Effective Modern C++ 笔记(三)——一些关键字

1.要重写时加上override,不想被重写或继承时加上final

相信稍微接触过JAVA的程序员都知道上面的两个关键字是用来做什么的,在C++11中其实也大同小异。

1.被加上final关键字的结构体或者类不允许被继承

struct B1 final { };
struct D1 : B1 { }; // 错误!

2.被加上final关键字的函数不允许被重写

struct B2
{
    virtual void f() final {}
};
struct D2 : B2
{
    virtual void f() {}// 错误!
};

3.被加上override关键字的函数必须重写其父类的函数

struct B4
{
    virtual void g(int) {}
};
struct D4 : B4
{
    virtual void g(double) override {}// 错误!
};

上面的两个关键字不仅能帮我们发现和避免很多很难发现的程序错误,而且能确确实实地让编译器作出许多优化。比如标记了finalvirtual函数将不会出现在虚表中,而标记为final的类则根本不会生成虚表。

函数重写触发的条件:

  1. 要被重写的基类函数必须是虚函数;
  2. (除了析构函数)基类和派生类的函数名必须一致;
  3. 参数类型,返回值类型,异常声明,是否const等必须一致;
  4. 对于C++11,还要求引用修饰子也必须一致

因此,override并不是多此一举,尤其对于C++来说。

2.对于不允许或者不可能抛出异常的函数应该加上noexcept关键字

  • 如果被noexcept修饰的函数抛出了异常,编译器可以选择直接调用std::terminate()函数来终止程序的运行。
  • noexcept比基于异常机制的throw()在效率上会高一些,因为异常机制会带来一些额外开销,比如函数抛出异常,会导致函数栈被依次地展开(unwind),并依帧调用在本帧中已构造的自动变量的析构函数等。
  • noexcept被广泛地、系统地应用在C++11的标准库中,用于提高标准库的性能(尤其是move动作swap、内存释放函数、析构函数),以及满足一些阻止异常扩散的需求。

3.使用constexpr来验证常量的初始值是否是在编译时就确定

  • constexpr修饰的对象(包含基本类型)是常量,并且在编译时就可以确定其值。
  • constexpr修饰的函数,在编译时能够根据传入的常数返回对应的常量。
  • constexpr修饰的变量,只能用字面常量或者constexpr函数的返回值初始化。
    实例:
#include <iostream>
#include <array>
constexpr int pow(int base, int exp) noexcept {
  int out = 1;
  for(int i = 0; i < exp; i++) {
    out *= base;
  }
  return out;
}
int main() {
  std::array<int, pow(3, 3)> ary;
  std::cout << ary.size() << std::endl; // 27
}

使用constexpr的好处:

  1. 强制的语法约束,保证程序的正确语义;
  2. 编译器可以将constexpr表达式或者函数直接替换成结果字面量,同时避免了宏的额外开销

4.使用volatile关键字保证对特殊地址的稳定访问

如果某一个变量可能被某些编译器未知的因素更改(如:操作系统、硬件或者其他线程),那么最好使用volatile关键字来修饰它,保证系统总是重新从它所在的内存读取数据。
一般来说,volatile用在以下的几个地方:

  1. 中断服务程序中修改的供其他程序检测的变量;
  2. 多任务环境下各任务间共享的变量;
  3. 存储器映射的硬件寄存器

5.使用mutable关键字突破const的限制

  • mutable修饰的变量将永远处于可变的状态,即使是在一个const函数、const结构体或者const类对象中。
  • mutable在类中只能修饰非静态数据成员。
  • 使用const修饰的函数或者类对象一般不能修改其状态,这种承诺一般是语义层面的,但编译器会强制进行严格的语法检查。尤其对于那些不会影响到结果的状态变量,其实可以放宽要求,这时候需要使用mutable关键字了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值