似乎在 C++(或者它是一般的 OOP 概念?)中,曾经是虚拟的
总是虚拟的东西。
我不会称它为“一次虚拟总是虚拟”,因为这听起来有点误导。虚拟性根本不是派生类的业务。虚函数都是关于 base 类的。它是基类,需要知道一个函数是否为虚函数,并在必要时进行虚函数调用。派生类函数可能会说“我不再是虚拟的了!”,但谁在乎呢?那时它已经通过虚函数调用被调用了。
C++11 final 不会改变这个运行时行为,它只是防止在编译时覆盖。
我正在寻找的是可能的、有效的,还是唯一的方法是
程序员要成为好公民并遵守类层次规则?
在 C++03 中,最简单的方法是提供良好的文档并在工作面试中只选择优秀的程序员 :)
但这可能不是您想要的。这里的技术解决方案是将您的类设计更改为 has-a 关系。 使整个类成为最终类的解决方法确实存在于 C++03 中。
所以,不是ConcreteSpecializedFactory is-a SpecializedFactory,而是SpecializedFactory has-a SpecializedFactoryImplementation。然后,您可以(可选地,为了更严格)使用friend 来允许后者仅从前者调用,并且(这是有趣的部分出现的地方)您可以使用虚拟继承技巧 从C++ FAQ "How can I set up my class so it won't be inherited from?" 到整个SpecializedFactory 类最终。
class SpecializedFactoryImplementation
{
public:
virtual ~SpecializedFactoryImplementation() {}
private:
SpecializedFactoryImplementation(SpecializedFactoryImplementation const &);
SpecializedFactoryImplementation &operator=(SpecializedFactoryImplementation const &);
friend class SpecializedFactory;
Object* CreateObject()
{
return DoCreateObject();
}
virtual Object* DoCreateObject() = 0;
};
class SpecializedFactoryBase
{
private:
friend class SpecializedFactory;
SpecializedFactoryBase() {}
};
class SpecializedFactory : public GeneralFactory, private virtual SpecializedFactoryBase
{
// ...
public:
SpecializedFactory(SpecializedFactoryImplementation* impl) :
m_impl(impl)
{
// null checking omitted for simplicity
}
private:
// the GeneralFactory base class should not be copyable
// anyway, so we do not have to worry about copy constructor
// or assignment operator
SpecializedFactoryImplementation* const m_impl;
virtual Object* CreateObject()
{
return m_impl->CreateObject();
}
};
以下内容将无法编译:
class SpecializedFactoryWrittenByEvilProgrammer : public SpecializedFactory
{
public:
SpecializedFactoryWrittenByEvilProgrammer() : SpecializedFactory(0) {}
private:
virtual Object* CreateObject()
{
return 0;
}
};
以下内容也不会编译:
// somewhere outside of SpecializedFactory:
SpecializedFactoryImplementation *s;
s->CreateObject();