在这里解读循环继承的好方法是什么?
class Node {
// ...
public:
list<Node*> neighbors() { /* ... */ }
void update() { }
}
template<class NodeType>
class HasImportance : public virtual NodeType {
double m_importance = 0.0;
public:
void receive_importance(double imp) { /* ... */ }
void give_importance() {
for (auto neighbor : this->neighbors())
neighbor->receive_importance(m_importance /* ... */);
}
};
class TrafficLight : public HasImportance<TrafficLight>, virtual Node {
public:
list<TrafficLight*> neighbors() { ... }
void update() { give_importance(); /* ... */ }
};
它失败(gcc 4.7.0),因为在尝试从它继承TrafficLight
时是不完整的类型。HasImportance
真正的问题是 HasImportance 需要知道
neighbors()
. 如果HasImportance
继承自
Node
,则它认为neighbors()
返回 的列表
Node*
,而不是TrafficLight*
,因此不知道它可以调用receive_importance()
这些项目。HasImportance
如果根本不继承类似的问题。
顺便说一句,我想做的是做一些混合来帮助轻松定义各种不同类型的图形,并分别对每个混合进行单元测试。例如,我应该能够通过编写类似class TrafficLight : public HasImportance, HasState<3>,
virtual Node { }
.
我想出了三种方法来解决这个问题,但看起来都很丑。(1)
static_cast<NodeType*>
。(2)TrafficLight
将其传递
this
给HasImportance
它的构造函数。这样,
HasImportance
根本不需要继承;它只存储一个指向 (ahem) 本身的指针,模板参数提供指针的类型。(3) 制作Node
一个类模板,如下所示:
template<class NodeType>
class Node {
public:
list<NodeType*> neighbors() { /* ... */ }
}
class TrafficLight : public HasImportance<Node<TrafficLight>> { /* ... */ }
编译后并没有引入 的无偿副本this
,但似乎……有点太好奇了。
这里有代码气味吗?我应该以完全不同的方式处理这些图表吗?