目录
一,final与override
C++对函数重写的要求比较严格,如函数名字母次序写反即无法构成重载,而这种错误在编译期间无法识别,只有在程序运行时没有得到预期结果才会发现得不偿失;因此C++11提供了关键字override和final,可帮助检测是否重写了;
final
- 修饰类,防止子类继承该类;
- 修饰虚函数,表示该虚函数不能在被重写;
class Car final{};
//不可将final类作为基类
class Benz :public Car {};
class Car
{
public:
virtual void Drive() final {cout << "Car" << endl;}
};
class Benz :public Car
{
public:
//报错,无法重写final函数
virtual void Drive() {cout << "Benz" << endl;}
};
override
- 检查派生类虚函数是否重写了基类某个虚函数,如没有编译报错;
class Car
{
public:
virtual void Drive() {cout << "Car" << endl;}
};
class Benz :public Car
{
public:
//报错,没有重写基类成员
virtual void Dri() override {cout << "Benz" << endl;}
};
二,默认成员函数的控制
在C++中,对于空类编译器会生成一些默认成员函数(如构造函数、拷贝构造函数、运算符重载、析构函数,&和const&重载、移动构造函数、移动拷贝构造函数等);如在类中显示定义了,编译器将不会重新生成默认版本;有时这些规则可能被忘记,最常见的是声明了带参数的构造函数,必要时则需要定义不带参数的版本以实例化无参的对象;而且有时编译器会生成,有时又不会生成,容易产生混乱,于是C++11让程序员可以控制是否需要编译器生成;
显式缺省函数
在C++11中可以在默认函数定义或声明时加上=default,从而显式的指示编译器生成该函数的默认版本,用=default修饰的函数称为显示缺省函数;
class A
{
public:
A(int a)
:_a(a)
{}
A() = default; //显式缺省构造函数,由编译器生成
A& operator=(const A& a); //在类中声明,在类外定义时让编译器默认生成
private:
int _a;
};
A& A::operator=(const A& a) = default; //显式缺省赋值重载函数,由编译器生成
删除默认函数
如想限制某些默认函数的生成,在C++98中将函数设置成private并且不给定义,这样只要调用就会报错;在C++11中更简单,只需在该函数声明加上=delete即可,该语法指示编译器不生成对应函数的默认版本,称=delete修饰的函数为删除函数;
注意,避免删除函数和explicit一起使用;
//C++98
class A
{
public:
A(int a)
:_a(a)
{}
private:
A();
A& operator=(const A& a);
private:
int _a;
};
class A
{
public:
//禁止编译器生成默认的拷贝构造和赋值运算符重载
A() = delete;
A& operator=(const A& a) = delete;
//避免与explicit一起使用
explicit A(int a) = delete;
private:
int _a;
};