It seems that in C++ (or is it general OOP concept?) the once virtual
always virtual thing holds.
I would not call it "once virtual always virtual", because that sounds a bit misleading. Virtuality is simply not the business of derived classes. Virtual functions are all about base clasess. It is the base class which needs to know whether a function is virtual or not, and make a virtual function call if necessary. The derived-class function may say "I am not virtual anymore!", but who cares? It's been invoked through a virtual function call already at that point.
C++11 final
does not change anything about this run-time behaviour, it just prevents overriding at compile time.
Is what I am looking for possible, and valid, or the only way is for
programmers to be good citizens and follow class hierarchy rules?
In C++03, the easiest way would be good documentation and selecting only good programmers at job interviews :)
But that's probably not what you are looking for. A technical solution here would be to change your class design to a has-a relationship. Workarounds to make entire classes final do exist in C++03.
So, rather than ConcreteSpecializedFactory
is-a SpecializedFactory
, make it SpecializedFactory
has-a SpecializedFactoryImplementation
. You can then (optionally, for even more strictness) use friend
to allow the latter to be called only from the former, and (and this is where the interesting part comes) you can use the virtual inheritance trick from the C++ FAQ "How can I set up my class so it won't be inherited from?" to make the entire SpecializedFactory
class final.
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();
}
};
The following will then not compile:
class SpecializedFactoryWrittenByEvilProgrammer : public SpecializedFactory
{
public:
SpecializedFactoryWrittenByEvilProgrammer() : SpecializedFactory(0) {}
private:
virtual Object* CreateObject()
{
return 0;
}
};
And the following will not compile, either:
// somewhere outside of SpecializedFactory:
SpecializedFactoryImplementation *s;
s->CreateObject();