【C++】final/override、如何设计一个不能被继承的类

  finaloverride 都是在特定场景使用有特殊含义的标识符(specifier / identifier ),并不是C++保留的关键字(not a reserved keyword )。

一、final specifier (since C++11)

Specifies that a virtual function cannot be overridden in a derived class or that a class cannot be inherited from.
final is an identifier with a special meaning when used in a member function declaration or class head. In other contexts it is not reserved and may be used to name objects and functions.

  即:用于指定一个虚函数不能在派生类中被重写,或一个类不能被继承
  也就是 final 标识符作用的对象就是: 或者 虚函数,且 final 是在成员函数定于或类头部时有特殊含义的标识符,但不是C++保留的关键字,可以被用于对象和方法的命名。
  主要有 种用法:

  1. 用于虚函数的声明或定义
  2. 用于类的定义
1.1 用于虚函数的声明或定义

  用途:限定这个虚函数不能被继承类重写(may not be overridden by derived classes)。且限定修饰的函数必须是虚函数。
  位置:用于虚函数声明时,紧跟虚函数声明后边,且位于纯虚函数限定符(pure-specifier,即 = 0)前边(如果有的话),如下。

struct Base {
	virtual void foo();
};

struct A : Base {
	void foo() final; // Base::foo is overridden and A::foo is the final override
//	void bar() final; // Error: non-virtual function cannot be overridden or be final
};

struct B final : A { // struct B is final
//	void foo() override; // Error: foo cannot be overridden as it's final in A
};

//struct C : B // Error: B is final
//{
//};
1.2 用于类的定义

  用途:限定这个类不能被继承(cannot be derived from)。
  位置:紧跟在类名后边,在 : 前边,如上 B,及如下 A

class A final
{
};

class B : A {};	// Errpr: "B" : 无法从"A"继承,因为它已被声明为"final"
1.3 用于union

  final 还可以被用作与 union 中,但是除了使用 is_final 输出类型以外,没有别的用处,因为 union 本身就不能被继承:

#include <iostream>
#include <type_traits>	// is_final
using namespace std;

class A {};
class B final {};
union UA {};
union UB final {};

int main() {
	cout << boolalpha
		 << is_final<A>::value << '\n'		// false
		 << is_final<B>::value << '\n'		// true
		 << is_final<UA>::value << '\n'		// false
		 << is_final<UB>::value << '\n';	// true
}

二、override specifier (since C++11)

Specifies that a virtual function overrides another virtual function.
override is an identifier with a special meaning when used after member function declarators: it’s not a reserved keyword otherwise.

  即:用于指定一个虚函数重写了另一个虚函数override 是在成员函数后边时候有特殊含义的标识符,但是不是C++保留的关键字

1.1 用于虚函数的声明或定义

  用途:保证所修饰的函数是虚函数,且重写了基类的对应虚函数。也就是起到了辅助检查的作用,保证重写,且没有写错重写函数。且被 final 修饰的虚函数不能 override
  位置:和 final 用于虚函数时一样。

struct A {
	void foo() {}
	virtual void func(int) {}
};

struct B : A {
	virtual void func(int) override {}	  // OK
//	virtual void func(double) override {} // Error: "B::func":包含重写说明符"override"的方法没有重写任何基类方法
//	void foo() override {}				  // Error: 同上
};

三、“如何设计一个不能被继承的类”

  问题其实是 “如何设计一个不能被继承的类,但不影响自身使用的类?”。
  用C++11的话,如上所述,加一个 final 标识符就可以了,但是面试时候肯定问这个问题肯定会问如果不能用C++11,怎么实现?
  解决方案为:使用友元、私有构造函数、虚继承等方式可以使一个类不能被继承

  参考 https://my.oschina.net/cuilili/blog/323696

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值