八叶一刀·无仞剑

万物流转,无中生有,有归于无

导航

C++11的override、default和delete关键字

Posted on 2021-04-09 20:20  闪之剑圣  阅读(2728)  评论(0编辑  收藏  举报

最近在参与组里的项目时接触了很多以前自己没太了解的C++语法(尤其是C++11以后出现的),今天给大家讲一下C++11新出的override和default关键字。
override关键字主要在声明类的成员函数时使用,它的作用就是告知程序员和编译器这个函数是重写了父类的虚函数,一方面代码的阅读者看到这个关键字标识就知道这是一个重写的函数;另一方面也给编译器进行检测:如果这个函数实际上没有重写父类的虚函数则会报错:

class A
{
public:
  virtual void func1();
  void func2();
};

class B:public A
{
public:
  //A的func1是虚函数,可以编译通过
  void func1() override;
  //A的func2不是虚函数,编译器会报错
  void func2() override;
};

至于另一个关键字default,它是在强行指定某个构造函数为默认构造函数。众所周知,当一个类声明了一个带参数构造函数后,编译器便不会再帮助该类生成默认构造函数,此时可以通过=default显式将某个构造函数定义为默认构造函数(当然这个函数的参数要符合规范,也不需要定义的)。其实不止默认构造函数,也可以以此定义默认拷贝构造函数和析构函数,对每个特殊成员函数统一使用=default语法也使得使代码更容易阅读。
下面的代码通过default定义了A的默认构造函数和默认拷贝构造函数,也包括默认析构函数:

class A
{
public:
    A() = default;
    A(A&) = default;
    ~A() = default; 
};

最后我们来提一下delete关键字,在C++11之前,它只是用于释放内存空间。C++11为它增加了新的意义:禁用某个类的成员函数。比如我们如果不想让某个类对象被拷贝,可以通过delete语法修饰它的拷贝构造函数:

class A
{
public:
  A() = default;
  A(const A&) = delete;
  ~A() = default;
};


int main()
{
  A a;
  A b = a; //编译器会报错,因为此时a的拷贝构造函数已经被禁用了
  return 0;
}

delete还有一种常用的用法就是禁用某种类型转换的构造函数,使得无法将类转换为某种特定类型。

class A 
{ 
public: 
    A(int) {} 
    A(double) = delete;  
}; 

int main() { 
    A A1(1); 
    A A2(0.1);//编译器会报错,因为此时a从double构造的函数被禁用了
    return 0; 
} 

最后说一句,delete关键字不仅可以用来修饰成员函数,也可以修饰非成员函数。比如说,我们希望一个函数只接受float类型的参数,那我们可以这样设计:

void func(float) {}
void func(double)=delete;
void func(int)=delete;