Любопытное циклическое наследование со смесью -ins в C++

Каков хороший способ расшифровать циклическое наследование здесь?

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вообще не нужно наследовать; он просто хранит указатель на сам (кхм ), а параметр шаблона обеспечивает тип указатель. (3 )Создайте Nodeшаблон класса, подобный этому:

template<class NodeType>
class Node {
public:
   list<NodeType*> neighbors() { /*... */ }
}

class TrafficLight : public HasImportance<Node<TrafficLight>> { /*... */ }

Это компилируется и не создает бесплатную копию this, но это кажется… слишком любопытным.

Есть ли здесь запах кода? Должен ли я подходить к этим графикам полностью по-другому?

6
задан Ben Kovitz 3 July 2012 в 12:46
поделиться