C++ 11 final/overrid关键字

子类可以重写父类的方法,从而实现扩展自己的行为,但是某些情况下。

我们可能并不希望子类能够重新实现父类的方法,我们希望完全的终止重写行为,这个时候我们需要借助关键字:final.

C++11和JAVA一样,使用关键字:final,来阻止子类对父类定义的方法进行重写.

g++ 210.cpp -o test -std=c++11

#include <iostream>
using namespace std;

class Base {

public:
	void msg1() {
		cout << "Base::msg1()" << endl;
	}
	virtual void msg2() {
		cout << "Base::msg2()" << endl;
	}

	virtual void msg3()  {
		cout << "Base::msg3()" << endl;
	}
};

class Derived : public Base {
public:
	void msg1()  {//不允许使用final ,msg1不是virtual函数
		cout << "Derived::msg1() " << endl;
	}

	void msg2() final {
		cout << "Derived::msg2() " << endl;
	}

	void msg3() {
		cout << "Derived::msg3() " << endl;
	}
};

class MyMsg :public Derived {
public:

	void msg1() {//不允许使用final ,msg1不是virtual函数
		cout << "MyMsg::msg1() " << endl;
	}

//	void msg2() {
//	}  //不合法,无法重写final函数

	void msg3() {
		cout << "MyMsg::msg3() " << endl;
	}
};


int main()
{
	Base* base = new Derived;
	base->msg1(); //无virtual 关键字
	base->msg2();//有virtual 关键字 --会实现动态编连

	//继承类重写的函数,自动具有virtual属性,会实现动态编连
	Derived* msg = new MyMsg;
	msg->msg3(); //调用MyMsg的msg3

	return 0;
}

执行结果输出如下:

Base::msg1()
Derived::msg2()
MyMsg::msg3()

注意 :final关键字只能用在virtual方法中,只能用于在中途终止派生类的重写行为.

补充知识点:
在C++中重载有一个特点,就是对于基类中声明为virtual的函数,之后的重写版本都不需要再声明为virtual了,即使在派生类中声明了关键字virtual,也会自动被编译器所忽略的.

OK,到了这里,我们会发现一个问题。

我们看继承类Derived,这个类我们是继承于Base,并且重写了Base的方法msg1() msg2().
但是注意这里,我们会引发出一个问题:

如果我们不看Base,或者继承的层次多了,我们就会犯一个迷糊:

这个时候,我们已经无法判断出msg1,msg2到底是Derived的私有方法,还是重写的父类的方法.

所以我们引入了override关键字来帮助我们进行区分.

class Derived : public Base {
public:
	void msg1()  {//不允许使用final ,msg1不是virtual函数
		cout << "Derived::msg1() " << endl;
	}

	void msg2() final {
		cout << "Derived::msg2() " << endl;
	}

	void msg3() {
		cout << "Derived::msg3() " << endl;
	}
};

所以改进后的写法是:

class Derived : public Base {
public:
	void msg1()  {//不允许使用final ,msg1不是virtual函数
		cout << "Derived::msg1() " << endl;
	}

	void msg2() final {
		cout << "Derived::msg2() " << endl;
	}

	void msg3() override {
		cout << "Derived::msg3() " << endl;
	}
};

这样我们就很容易的知道:

msg3()这个方法其实是重写的基类的方法.

注意:
override和final一样,只能用于virtual函数,非virtual函数使用final和override关键字一律不合法.

使用override声明的函数不能重写基类成员.

为什么呢?因为override设计的本意是告诉你此函数是纯虚函数,可是基类成员函数如果不纯虚函数而又添加了override,那么就失去了意义了.

猜你喜欢

转载自blog.csdn.net/zhangkai19890929/article/details/83586202