1.override
修饰的是 继承的虚函数,表明这是重写的基类的虚函数。
目的是为了让编译器辅助检查是否真正重写了继承的虚函数,而没有重写错了参数类型和个数,造成对基类同名函数的隐藏。
所以在实际开发中,在重写继承而来的虚函数时,建议加上关键字override。
如下代码就有问题:
struct B3
{
virtual void g(int) {}
};
struct D3 : B3
{
virtual void g(double) override {} // "does not override"
};
2.final
修饰的是 类或者虚函数,表明 此类 或 此虚函数 不能被继承。
目的是为了让编译器辅助检查是否不应该继承此类和此虚函数。
如下代码就有问题:
struct B1 final { }; // 修饰类
struct D1 : B1 { }; // "cannot derive from 'final' base"struct B2
{
virtual void f() final {} // "overriding final function" 修饰虚函数
};
struct D2 : B2
{
virtual void f() {} // "cannot derive
};
3.default
default关键字,用来显式地要求编译器为我们生成类的特殊成员函数。
类中有6个特殊成员函数,如果用户不声明,编译器会隐式生成:默认构造函数、拷贝构造函数、析构函数和赋值运算符函数,以及C++11中新增的两个 “特殊成员函数” ——移动构造函数和移动赋值运算符函数。
1)错误使用:
class X {
public:
int f() = default; // 错误 , 函数 f() 不是类X的特殊成员函数
X(int,int) = default; // 错误 , 构造函数 X(int, int) 不是类X的特殊成员函数
X(int = 1) = default; // 错误 , 默认构造函数 X(int=1) 含有默认参数
};
2)Defaulted 函数既可以在类体里(inline)定义,也可以在类体外(out-of-line)定义:
class X{
public:
X() = default; //Inline defaulted 默认构造函数
X(const X&);
X& operator = (const X&);
~X() = default; //Inline defaulted 析构函数
};
X::X(const X&) = default; //Out-of-line defaulted 拷贝构造函数
X& X::operator = (const X&) = default; //Out-of-line defaulted 拷贝赋值操作符
4.delete
default关键字,用来禁止修饰的函数的生成。(包括上面的类的特殊成员函数 普通成员函数 以及 普通的函数 以及一些操作符)
1)必须在函数第一次声明的时候将其声明为 deleted 函数,否则编译器会报错:
即对于类的成员函数而言,deleted 函数必须在类体里(inline)定义,而不能在类体外(out-of-line)定义(跟default不同)。例如:
class X {
public:
X(const X&);
};X::X(const X&) = delete; // 错误,deleted 函数必须在函数第一次声明处声明
2)在函数重载中,用delete来滤掉一些函数的形参类型(阻止一些自动类型转换)
int add(int,int) = delete;
double add(double a,double b){
return a+b;
}
cout << add(1,3) << endl; // 错误,调用了 deleted 函数 add(int, int)
cout << add(1.2,1.3) << endl;