您的位置:首页 > 其它

final和override的用法

2015-07-03 14:30 246 查看


原文:C++11 新特性:显式 override 和 final

2012 年 3 月 22 日,GCC 4.7.0 正式发布。从这个版本开始,GCC 增加了许多新的 C++ 11 的特性。今天我们要介绍的是其中的一个特性:显式的使用
final
override
关键字。先来看下面的例子:

C++

123struct B1 final { }; struct D1 : B1 { }; // 错误!不能从 final 类继承!
上面的代码是错误的,因为 D1 试图继承 B1,而 B1 则声明为 final。很像 Java,不是吗?当然!还有另外的用法:C++

1

2

3

4

5

6

7

8

9

struct
B2

{

virtual
void
f()
final
{}
//
final 函数

};

struct
D2
:
B2

{

virtual
void
f()
{}

};

这段代码又会出错,因为
D2::f
重写了
B2::f
,但是
B2::f
却被声明为
final 的!

下面再看另外一段代码:

C++

123456789struct B3{ virtual void f() {}}; struct D3 : B3{ void f() {}};
开发 D3 的程序员真的想重写
B3::f
函数吗?还是说,他只是不小心写了个与父类同名的函数,却在不经意间导致了覆盖?为了避免这种错误,C++ 11 引入了
override
关键字(多么像 C# 啊!)。于是,我们会发现,下面的一段代码是会出错的:C++

1

2

3

4

5

6

7

8

9

10

struct
B4

{

virtual
void
g(int)
{}

};

struct
D4
:
B4

{

virtual
void
g(int)
override
{}
//
OK

virtual
void
g(double)
override
{}
//
Error

};

多亏了
override
关键字,我们可以让编译器帮我们检测到这个很难发现的程序错误。这段代码的错误在于,
override
关键字表明,
g(double)
虽然想要进行
override
的操作,但实际父类并没有这么个函数。

值得注意的是,这些并不是一些语法糖,而是能确确实实地避免很多程序错误,并且暗示编译器可以作出一些优化。调用标记了
final
virtual
函数,例如上面的
B2::f
,GNU
C++ 前端会识别出,这个函数不能被覆盖,因此会将其从类的虚表中删除。而标记为
final
的类,例如上面的 B1,编译器则根本不会生成虚表。这样的代码显然更有效率。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: