2012-08-02 90 views
0

你好我正在編寫一個程序,顯示/顯示和基準不同的圖形。一個圖是由節點和邊緣的...所以我的問題是,我有兩個模板類(模板),這是所有派生類出現在另一個模板類C++相互依存的類模板,指針鑄造派生類

template <class Node> 
class Edge 
{ 
public: 
    Edge() : startN(0), endN(0), price(0) {} 
    Edge(Node *startN, Node *endN, int price) : startN(startN), endN(endN), price(price) 
    { 
     startN->toEdges.push_back(this); // PROBLEM HERE 
     endN->fromEdges.push_back(this); // PROBLEM HERE 
    } 

    Node *startNode() const { 
     return startN; 
    } 
    Node *endNode() const { 
     return static_cast<Node *>(endN); 
    } 
    int getPrice() const { 
     return price; 
    } 
    void setPrice(int price) { 
     this->price = price; 
    } 

private: 
    Node *startN; 
    Node *endN; 

    int price; 
}; 


template<template<class> class EdgeTemplate > 
class NodeBase 
{ 
public: 
    NodeBase() : nodeId(0), key(0), state(UNLABELED), prev(0) {} 
    NodeBase(int id, int key) : nodeId(id), key(key), state(UNLABELED), prev(0) {} 

    void addToEdges(EdgeTemplate<NodeBase> *edge) { 
     toEdges.push_back(static_cast<EdgeTemplate<NodeBase> *>(edge)); 
    } 

    int nodeId; 
    int key; 
    State state; 
    NodeBase *prev; // prevous scanned 

    QVector<EdgeTemplate<NodeBase> *> fromEdges; // start 
    QVector<EdgeTemplate<NodeBase> *> toEdges; // end 
}; 

錯誤基地:

template <template<class> class EdgeTemplate, class Node> 
class DijkstraAlgorithm { 
... 
QVector<EdgeTemplate<Node> *> Edges; // the problem for derived classes 
... 
}; 

鏘:

error: cannot initialize a parameter of type 'Edge<NodeBase<Edge> > *' with an rvalue of type 'Edge<DNode> *' 
     startN->addToEdges(this); 
          ^~~~ 

GCC:

error: no matching function for call to 'QVector<Edge<NodeBase<Edge> >*>::push_back(Edge<DNode>* const)' 

所以據我所知,問題是派生類DNodeclass DNode : public NodeBase <Edge>)不能存儲在基地類型NodeBase<Edge>的cointainer ...我試過鑄造它,但它沒有奏效。

有人可以請解釋我做錯了什麼,我該如何解決這個問題?

回答

0

在查看模板時,繼承關係並不重要。

struct B {}; 
struct D : B {}; 

template<typename T> 
struct C {}; 

C<B> *c = new C<D>; // error C<D> is completely different and has no relationship to C<B> 

// you might as well say: 
float *f = new char[50]; 

考慮:

template<> 
struct C<B> { 
    int a,b,c; 
    int foo() { return a+b+c;} 
}; 

template<> 
struct C<D> { 
    std::string s; 
    std::string bar(); 
}; 

C<B> *c = new C<D>; // pretend it works. 
c->foo(); // C<D> doesn't have a,b or c and doesn't have a method foo... 

也許NodeBase應該只是採取邊緣型作爲模板參數,而不是邊緣模板。

template<typename Edge> struct NodeBase { 
    QVector<Edge *> fromEdges; 
}; 

然後DNode繼承NodeBase<Edge<DNode>>

有可能是一個更好的辦法,也許更直接的使用CRTP的,但它很難不看到越來越多的當前設計的說。

+0

,我不知道,並感謝您指出(繼承和模板)。如果我將addToEdges(EdgeTemplate * edge)更改爲addToEdges(void * edge),但代碼基準化過程變慢(減慢alg和時間),代碼將起作用。我會重新考慮這個程序的設計,並會考慮CRTP,如果失敗了,我會考慮你提出的解決方案。我的主要目標不是重複自己,更容易維護。並再次感謝您的回覆,這非常有幫助。 – S74nk0 2012-08-02 20:26:27

+0

建議的解決方案NodeBase >,像一個魅力工作,所以你的答案是非常有益的,再次感謝關於模板和繼承的簡短解釋。嘗試了幾件事情,但最終我仍然使用了您的解決方案。謝謝! – S74nk0 2012-08-03 22:43:38