看到C++0x中可以使用最终虚函数,我有点困惑。与一开始就省略这两个修饰符有什么区别?
这种区别发生在使用它的不是基类而是派生类时。
class Base {
virtual void foo() = 0;
};
class Derived : Base {
void foo() {}
// Still virtual because it's virtual in base- no way to "un-virtual" it
virtual void foo() final {}
// Now un-overridable.
};
将其视为防止覆盖的不是全部,而是防止“更多”的覆盖。
final
关键字与virtual
连用时,我也想到了这个问题:
如果声明一个方法
virtual
使它可继承和重写,并且声明一个方法final
防止该方法被重写,那么声明一个方法同时会形成矛盾吗?
我认为这个问题的当前被接受的答案很好,但基于我所发现的内容,我想进一步说明它。
考虑以下类:
class A {
public:
void hide_me();
virtual void override_me();
virtual void cant_override_me() final;
};
void hide_me();
这个函数是非虚函数,因此根据定义无法被覆盖。
第三个:
virtual void cant_override_me() final;
被声明为final
,因此不能被覆盖,这也是其定义。
区别在于,由于hide_me
是非虚函数,所以无法对其进行覆盖,而您可以将cant_override_me
视为有资格被覆盖的(因为它是virtual
),但是由于final
修饰符,它也禁止了覆盖。换句话说,对于未声明为virtual
的方法,不适用覆盖,但对于virtual
方法,适用覆盖,只是如果它们也被声明为final
,则无法覆盖它们。
现在考虑一个子类:
class B: public A {
public:
void hide_me(); // this hide's A's definition of "hide_me()"; this is not overriding.
void override_me(); // implicit "virtual"
//void cant_override_me(); // implicit "virtual"; compilation fails
};
B
中的 hide_me()
方法,但这只是重载或 隐藏,因此函数名不同。通过 A::hide_me()
,B
仍然可以访问 A
的 hide_me
方法,但其他人如果使用声明为 B
的引用,则无法访问。B *my_b = new B();
必须通过my_b->A::hide_me()
访问A
现在隐藏的hide_me
定义。
你不能在B
中提供cant_override_me()
的重新定义。
以下是一个完整示例,稍微重新定义了程序以帮助说明正在发生的事情:
#include <cstdio>
class A {
public:
inline void hide_me() {
printf("a hide_me\n");
}
virtual void override_me();
virtual void cant_override_me() final;
};
class B: public A {
public:
inline void hide_me() {
printf("b hide_me\n");
}
void override_me();
inline void foo() {
A::hide_me();
}
// can't override cant_override_me
};
void A::override_me() {
printf("a override_me\n");
}
void A::cant_override_me() {
printf("a cant_override_me\n");
}
void B::override_me() {
printf("b override_me\n");
}
int main (int argc, char *argv[]) {
A *a = new A();
A *ab = new B();
B *b = new B();
a->hide_me();
ab->hide_me();
b->hide_me();
b->A::hide_me();
printf("---\n");
a->override_me();
ab->override_me();
b->override_me();
b->A::override_me();
}
a hide_me
a hide_me
b hide_me
a hide_me
---
a override_me
b override_me
b override_me
a override_me
Base
继承自另一个类,该类声明了初始基础f
方法。 - Damien_The_Unbeliever