似乎在C ++中(或者是通用的OOP概念?),曾经的虚拟总是虚拟的东西成立了。我想知道是否可以将其停止。我有这种情况需要我的要求。
假设我有一个像这样的Factory类
class Object;
class GeneralFactory
{
private:
virtual Object* CreateObject() = 0;
};
现在,我有一个专门的工厂,该工厂仍然可以创建对象但具有更多控制权。
class SpecializedFactory : public GeneralFactory
{
private:
virtual Object* CreateObject();
virtual Object* DoCreateObject() = 0;
};
这个想法是让
SpecializedFactory::CreateObject
在其实现中使用DoCreateObject
。但是实际上,类可以从SpecializedFactory
派生并覆盖CreateObject
,从而破坏了良好的意图。我是在寻找可行且有效的方法,还是让程序员成为好公民并遵循类层次结构规则的唯一途径?
什么是合适的替代品?我正在使用C ++ 03 FYI。
最佳答案
似乎在C ++中(或者是通用的OOP概念?)
总是虚拟的东西。
我不会称其为“一次虚拟总是虚拟”,因为这听起来有点误导。虚拟性根本不是派生类的事。虚拟功能全都与基本情况有关。它是基类,需要知道一个函数是否为虚函数,并在必要时进行虚函数调用。派生类函数可能会说“我不再是虚拟的!”,但是谁在乎呢?此时已经通过虚拟函数调用来调用它。
C ++ 11 final
不会对此运行时行为进行任何更改,只是防止在编译时进行覆盖。
我在寻找的是可能的,有效的方法,还是唯一的方法是
程序员要成为好公民并遵循班级等级规则?
在C ++ 03中,最简单的方法是编写好的文档,并在面试时只选择优秀的程序员:)
但这可能不是您想要的。这里的一个技术解决方案是将您的班级设计更改为“拥有”关系。在C ++ 03中确实存在使整个类最终化的解决方法。
因此,使ConcreteSpecializedFactory
具有-a SpecializedFactory
而不是SpecializedFactory
是-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();