我的C ++程序中有一个非常特殊的情况。
查看以下课程设置:
class Base1 {
public: void baseMethod();
}
class Base2 : public Base1 {
...
}
class Common {
public: void commonMethod();
}
class Derived1 : public Base1, public Common {
...
}
class Derived2 : public Base2, public Common {
...
}
Base1
和Base2
对我来说是不可更改的,因为它们是图书馆的一部分。
我想要实现的是Derived1
和Derived2
共享相同的方法commonMethod()
,因此我使用该方法的类Common
作为{的公共基础{1}}和Derived1
。
现在的问题是Derived2
应该包含对commonMethod()
中baseMethod()
的定义的调用!在Base1
- 或Derived1
- 对象的上下文中,这是合法的,但如何在Derived2
中定义该方法?
我知道如果我将Common
声明为Base2
的虚拟派生类,Base1
则相同,那么它应该不是问题(至少Common
},不确定Derived2
)。但是,因为我无法修改Derived1
无论如何都不可能。
同样让Base2
继承Common
然后Base2
和Derived1
仅来自Derived2
不起作用,因为我不想{{1}继承自Common
!
我想到的是在Derived1
内制作dynamic_cast:
Base2
这似乎有效,但我不确定这是否是一个“好”的解决方案......
你有什么想法让它变得更好吗?或者你认为这个解决方案一点都不差? :)
答案 0 :(得分:1)
如果Common
的唯一目的是提供该方法的通用实现,则可以使用CRTP模式并将其模板化为基类型。此时,您可以决定将它保留为DerivedX
类型的多个基础是否有意义,或者将继承层次结构线性化是否有意义:
// Option1
template <typename Derived>
struct Common {
void commonFunction() { ... static_cast<Derived*>(this)->foo(); ... }
};
struct Derived1 : Base1, Common<Derived1>
// Option2 (not strictly CRTP, but close)
template <typename Base>
struct Common : Base {
void commonFunction() { ... this->foo(); ... } // keep the this-> here
};
struct Derived1 : Common<Base1>
答案 1 :(得分:1)
如果我是你,我会在 多重继承 上选择 组合 ,即定义{{ 1}}作为派生类的成员对象。
common
虽然有这样的潜在风险。由于成员对象(class Base1 {
public: void baseMethod();
}
class Base2 : public Base1 {}
class Common {
public:
Common(Base1 *base): m_base(base) {}
void Common::commonMethod()
{
m_base->baseMethod();
}
private:
Base1 *m_base;
}
class Derived1 : public Base1
{
public:
Derived2(): m_common(this) {}
private:
Common m_common;
}
class Derived2 : public Base2
{
public:
Derived2(): m_common(this) {}
private:
Common m_common;
}
)首先在外部对象(Common
或Derived1
)之前构造,因此您需要确保在Derived2
对象中没有调用任何方法{ {1}}的构造函数。