2015-04-04 58 views
1

設置一個公共屬性作爲私人

class vertex{ 

    // ... 

}; 

我tryng設置此公共屬性作爲私有。

vector<edge> edges; 

但這裏

void addedge(int from, int to, int length=-1) { 
    vertices[from].edges.push_back(edge(to, length)); 
} 

這裏

edge &e = vertices[u].edges[i]; 

我不明白我怎麼能有機會與像在其他情況下的方法到邊緣。

完整代碼:

#define MAX_VER 1000 
#define INFINITE 9999 
#include <vector> 
#include <queue> 
#include <iostream> 
using namespace std; 
class edge{ 
    private: 
     int to; 
     int length; 
    public: 
     edge(int to, int length) : to(to), length(length) {} 
     int getTo(){return to;}; 
     void setTo(int t){to=t;}; 
     int getL(){return length;}; 
     void setL(int l){length=l;}; 
}; 
class vertex{ 
    private: 
     //vector<edge> edges; 
     int dis; 
     int prev; 
    public: 
     vector<edge> edges; 

     vector<edge> get_edges(){return edges;} 

     int getDis(){return dis;}; 
     void setDis(int d){dis=d;}; 
     int getPrev(){return prev;}; 
     void setPrev(int p){prev=p;}; 
}; 
class graph{ 
    private: 
     vertex vertices[MAX_VER]; 
    public: 
     void reset() { 
      for (int i=0; i < MAX_VER; i++) { 
       vertices[i].get_edges().clear(); 
       vertices[i].setDis(INFINITE); 
       vertices[i].setPrev(-1); 
      } 
     } 

     void addedge(int from, int to, int length=-1) { 
      vertices[from].edges.push_back(edge(to, length)); 
     } 
     typedef pair<int, int> pp; 
     void dijkstra(int source) { 
      priority_queue<pp, vector<pp>, greater<pp> > q; 
      vertices[source].setDis(0); 
      q.push(make_pair(0, source)); 
      while (!q.empty()) { 
       int u = q.top().second; 
       int dis = q.top().first; 
       q.pop(); 
       if (dis > vertices[u].getDis()) 
        continue; 
       for (int i = 0; i < vertices[u].get_edges().size(); i++) { 
        edge &e = vertices[u].edges[i]; 
        if (dis + e.getL() < vertices[e.getTo()].getDis()) { 
         vertices[e.getTo()].setDis(dis + e.getL()); 
         vertices[e.getTo()].setPrev(u); 
         q.push(make_pair(vertices[e.getTo()].getDis(), e.getTo())); 
        } 
       } 
      } 
      cout << "Distance from vertex 2 to 4 is: " << vertices[4].getDis() << endl; 
     } 
}; 
int main() { 
    graph g; 
    g.reset(); 
    g.addedge(0, 1, 5); 
    g.addedge(0, 2, 9); 
    g.addedge(0, 3, 4); 
    g.addedge(0, 4, 6); 
    g.addedge(1, 2, 2); 
    g.addedge(1, 3, 5); 
    g.addedge(1, 4, 7); 
    g.addedge(2, 3, 1); 
    g.addedge(2, 4, 8); 
    g.addedge(3, 4, 3); 
    g.dijkstra(2); 
    return 0; 
} 
+0

您的get_edges方法按值返回邊,您希望通過引用返回它們。但是,結果與您將邊緣公開時幾乎相同。我想你真正想要做的是寫入像addEdge和getEdge這樣的方法來處理你的頂點類,而不是公開地公開地暴露它們。 – hynner 2015-04-04 21:39:33

+0

如果您想從類外部訪問邊緣變量,請使用'get_edges'函數。 – 2015-04-04 21:41:32

+0

'vector getEgdes()const'應該做這個工作 – 2015-04-04 21:41:46

回答

1

edges應該是私有成員,通過公共get功能訪問。您已經定義了這樣的事情(get_edges()),但它沒有正確定義:

class vertex 
{ 
    //... 

public: 
    vector<edge> edges; 

    vector<edge> get_edges(){return edges;} 

    //... 
}; 

你可以通過值,這意味着返回成員,每一次這個函數被調用,一個新副本創建的edges和該副本返回!

你應該參考歸還和兩個constnon-const對象提供的版本:

class vertex 
{ 
    //... 

public: 
    vector<edge> edges; 

    vector<edge>& get_edges() { return edges; } 
    const vector<edge>& get_edges() const { return edges; } 

    //... 
}; 

此外,edges由類只使用。所以,這可能足以宣佈這兩個班級之間的友誼?

變化vertex類是這樣的:

class vertex 
{ 
    friend class graph; //declare friend 

private: 
    int dis; 
    int prev; 
    vector<edge> edges; //make 'edges' private 

public: 
    vector<edge>& get_edges() { return edges; } 
    const vector<edge>& get_edges() const { return edges; } 
}; 

從現在起,類將有機會獲得vertex類的所有private和protected成員,因爲它已被宣佈爲它的朋友。在簡單的情況下,這是最快速,侵入性較小的解決方案(但僅限於其他代碼,需要編寫)。

+0

非常感謝您的幫助。還有一件事。讓我知道如果聲明另一個類的朋友,我尊重封裝和OOP的約束? – Fabiospecial 2015-04-05 00:43:41

+0

是的,絕對。 OOP也是爲每個班級定義完整的,最小的和功能性的公共界面。但有時候,另一個班級可能需要訪問少數或更多的私人成員。爲了滿足其他類的實現邏輯而增加大量新的功能將是一個非常糟糕的設計。 – 2015-04-05 11:00:55