(Liskov Substitution principle)
我完蛋了,完全忘记虚拟继承了,面试的时候没想明白。(因为我编程也没用过虚拟继承,都是用静态的)。。。
somehow,我写出了一个很离谱的代码(某种拙略的 ECS 变种?之后一定要学习一下 ECS):
#define VIRTUAL_INHERIT
template <typename BASE>
struct defaultModule : virtual BASE {};
template <template <class> typename... MODULES>
struct mClass : MODULES<mClassImpl>... {};
template <typename BASE>
#ifdef VIRTUAL_INHERIT
struct loopModule : virtual BASE {
#else
struct loopModule : BASE {
#endif
void run() {
LOG_INFO_RAW("module");
BASE::run();
}
};
template <typename BASE>
#ifdef VIRTUAL_INHERIT
struct otherModule : virtual BASE {
#else
struct otherModule : BASE {
#endif
void other() { LOG_INFO_RAW("other module"); }
};
int main() {
mClass<defaultModule, loopModule, otherModule> classSupportLoop{};
#ifdef VIRTUAL_INHERIT
classSupportLoop.run();
#else
classSupportLoop.loopModule::run();
#endif
classSupportLoop.other();
loopModule<mClassImpl>* l = &classSupportLoop;
otherModule<mClassImpl>* o = &classSupportLoop;
#ifdef VIRTUAL_INHERIT
LOG_DEBUG_RAW("the addr of int member is: %p, %p, %p", &l->data, &o->data,
&classSupportLoop.data);
#else
LOG_DEBUG_RAW("the addr of int member is: %p, %p, %p", &l->loopModule::data,
&o->otherModule::data, &classSupportLoop.defaultModule::data);
#endif
return 0;
}
我想要避免 virtual inheritance,发现,然,我违反了面向对象的liskov替代原则。Java 就没有菱形继承(接口,然而接口之间是不实现东西的)。
It is based on the concept of "substitutability" – a principle in object-oriented programming stating that an object (such as a class) and a sub-object (such as a class that extends the first class) must be interchangeable without breaking the program
来自 <https://en.wikipedia.org/wiki/Liskov_substitution_principle>
但是实际就是,我想通过继承实现非 OOP 的概念,而是组合的概念。但是,有没有一种设计模式能够避免采用继承帮我实现他呢?
结论是无法解决。。。
but,实际用继承来做这个能够实现一个没有 virtual inheritance 的功能。
一个是 stateless 的,因此不需要 virtual,等于扩展接口。
一个是把数据分离出去。还有一个是这样的,
就是一个外部 facade 类只是一个组合,这些 module 本身并没有 interfere 的部分,这个是最好的情况。接下我按这个去走看看。