是否可以像在Java中一样创建我的成员函数final
,以便派生类不能覆盖它们?
答案 0 :(得分:23)
C ++ 11添加了final
上下文关键字来支持此功能:
class B
{
public:
virtual void foo() final;
};
class D : B
{
public:
virtual void foo(); // error: declaration of 'foo' overrides a 'final' function
};
GCC 4.7和Clang 3.0支持 final
。正如Sergius在他的回答中指出的那样,自MSVC ++ 2005以来,MSVC ++支持它(拼写sealed
)。因此,如果您封装在一个迷你宏中并根据您的编译器进行设置,那么您可以使用它。只要确保你实际上 至少每隔一段时间使用这样的编译器,这样你就可以及早发现任何错误。
答案 1 :(得分:9)
它实际上是默认行为。即如果你没有明确地将你的类实例方法声明为virtual
,那么它们在子类中不能是overridden(只有hidden,这是一个不同的 - 几乎总是错误的 - 情况)
Effective C ++ Third Edition,Item 36详细论述了这一点。考虑
class B {
public:
virtual void vf();
void mf();
virtual void mf(int);
...
};
class D: public B {
public:
virtual void vf(); // overrides B::vf
void mf(); // hides B::mf; see Item33
...
};
D x; // x is an object of type D
B *pB = &x; // get pointer to x
D *pD = &x; // get pointer to x
pD->vf(); // calls D::mf, as expected
pB->vf(); // calls D::mf, as expected
pD->mf(); // calls D::mf, as expected
pB->mf(); // calls B::mf - surprise!
pD->mf(1); // error - D::mf() hides B::mf(int)!
pB->mf(1); // calls B::mf(int)
所以这并不完全是final
在Java中的行为,但你只能用C ++来实现这一点。另一种方法可能是完全阻止子类化。技术 - 工作但不是很好 - 解决方案是声明所有构造函数private
(并提供静态工厂方法,如果你想允许实例化你的类)。
答案 2 :(得分:3)
从Bjarne检查this(我可以阻止人们从我的班级派生出来吗?)
答案 3 :(得分:1)
实际上,如果您使用MSVC,则可能。有sealed
个关键字。这是一个example from msdn。
答案 4 :(得分:1)
新的C ++ 11标准现在支持显式覆盖和成员函数的最终版本!