设置一个公共属性作为私人

问题描述:

设置一个公共属性作为私人

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

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