C++ 11带来了override关键字,用于成员函数声明之后,表示这是个虚函数,并重写了基类里的虚函数。
本文讲解override的一个妙用,用于避免掉进坑里。
一 坑的描述及解决
避坑1
下面是两个类,一个基类和一个子类,
class A
{
public:
virtual bool foo() {
};
};
class B : public A
{
public:
void foo() const
{
std::cout << "hello world\n";
}
};
然后我们写个main函数去使用class B,
int main(void)
{
A * ptr = new B();
ptr->foo();
return 0;
}
编译没问题,然后运行,结果什么都没有打印…
为什么呢?类A和B的定义,乍一看基类的函数foo被子类重写了,其实没有,因为子类函数声明后面加了const,这样这2个foo()函数的signature就不匹配。
程序运行时在子类中没有找到重写的foo()函数 (因为指针的类型是基类),这样就会去调用基类中的foo()函数。
如何避免?通过在子类foo()函数后面加上override,如下,
class B : public A
{
public:
void foo() const override
{
std::cout << "hello world\n";
}
};
这样编译时就会报错,提示并没有覆盖基类中的foo()函数,
避坑2
假如基类中的函数忘记写virtual,子类中函数重写了该函数(本意是想子类重写基类中的虚函数),
class A
{
public:
void bar() {
}
};
class B : public A
{
public:
void bar()
{
std::cout << "hehe\n";
}
};
下面是main函数,
int main(void)
{
A * ptr = new B;
ptr->bar();
return 0;
}
编译没问题,运行后发现什么都没有打印…
原理也比较简单,类B的bar()函数并不在虚函数表里,这样使用基类指针去调用时就无法找到B的bar()函数,只能去执行A的bar()函数。
但是如果在B的bar()函数声明后加上override,编译时就会给出错误了,
class B : public A
{
public:
void bar() override
{
std::cout << "hehe\n";
}
};
提示如下,
这样顺着这个就回去查看基类,就可以发现基类函数没有加virtual关键字。
二 总结
这里用该链接里的回答来总结下override的用处,
The override keyword serves two purposes:
- It shows the reader of the code that “this is a virtual method, that is overriding a virtual method of the base class.”
- The compiler also knows that it’s an override, so it can “check” that you are not altering/adding new methods that you think are overrides.
转载:https://blog.csdn.net/whahu1989/article/details/117535968
查看评论