首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不违反封装的情况下合法地访问和修改私有字段向量和映射?

如何在不违反封装的情况下合法地访问和修改私有字段向量和映射?
EN

Stack Overflow用户
提问于 2016-05-18 00:10:40
回答 2查看 91关注 0票数 1

我正在尝试将深度优先搜索作为一个函数来实现,它接受一个图形并输出DFS。

代码语言:javascript
运行
复制
class Graph
{
private:
  int V;
  int timestamp;
  std:: vector<std:: list<int> > graph;
  std:: map<int, vertex> nodemap;
public:
  Graph(int V);
  int Size();

  void addEdge(int u, int v);
  void printEdges();
  void printVertices();
};

上面是我为图表制作的课程。我正在尝试创建一个函数,返回指向私有向量和映射的指针,以便在图的邻接列表和地图数据结构上执行for循环操作。然而,我知道直接操作数据结构是对封装的违反,我想维护我的程序的面向对象的规则。如何才能做到这一点而不违反封装呢?

PS:,我不希望使用朋友函数,因为我不想让这个函数成为例外。我想找到一个主流的解决方案,它是程序员普遍使用的,是一个有纪律的解决方案。不过,如果需要,我可以更改我的类字段/可访问性。

谢谢您抽时间见我!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-18 00:26:44

如果您需要在邻接映射上迭代,则添加一个成员函数,允许您这样做。

你有两个明显的选择:

  1. 定义自己的AdjacencyMapIterator类,并提供返回这些类实例的begin() / end()
  2. 提供一个带有函子的函数,在邻接映射中的每个条目上调用函子。

第一个应该是这样的:

代码语言:javascript
运行
复制
for(auto it = graph.adjacency_begin() ; it!=graph.adjacency_end(); ++it) {
   vertex& v1 = it->v1;
   vertex& v2 = it->v2;
   ...
}

第二个看起来就像

代码语言:javascript
运行
复制
graph.for_each_adjacency(
   [](vertex& v1, vertex &v2) { .... }
);

最大的问题是如何在迭代期间处理图形结构的更改。我看到的大多数实现要么显式地不允许这样做(要么抛出异常,要么声明这样做是未定义的行为),或者在内部副本上操作迭代。如果你需要一些不同的东西--期待它成为未来的一个痛点。

如果您想在不允许在循环中进行更新的循环中执行某些更新,只需循环将所需的更新存储在某个地方,那么在循环完成后应用所有更新:

代码语言:javascript
运行
复制
std::vector<UpdateInfo> updates;
graph.for_each_adjacency( [&updates](const vertex& v1, const vertex& v2) { 
   updates.push_back( calculateUpdate(v1,v2) );
} );

foreach(updates, [&graph](const UdpateInfo &update) {
   applyUpdate(update, graph); 
} );
票数 0
EN

Stack Overflow用户

发布于 2016-05-18 00:23:51

你应该决定你是否是“面向对象的”。如果没有,那么您就有了一个结构(也就是记录),所以让您的字段公开并继续进行。但如果你是O-O还有几条路要走。您可以在Graph上提供访问器,例如,给定顶点返回边(或相邻顶点)的访问器。然后,在图的外部编写遍历算法。或者,您可以将遍历算法作为Graph的一种方法,并且它可以直接访问私有成员。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37288163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档