C++ 中类的划分和设计

发布于 2024-10-08 07:07:23 字数 2200 浏览 0 评论 0原文

在业余时间,我一直在为各种目的编写代码,并将它们改编成其他语言,只是为了看看那里有什么。目前,我正在采用最初用 Java 编写的遗传编程图形着色算法,并尝试将其强制转换为 C++。

我用于该任务的任意数据结构有几个类。在 Java 中,这对我来说并不是什么大问题,因为我已经接触它有一段时间了。图形结构仅创建一次,并为其分配了颜色。 着色(特别是找到一个最优化的颜色)是代码的真正要点。例如,我可以有一个 Graph 类,其中包含 NodeEdge 等内部类,或者我可以有一个包 graph 与类 GraphNodeEdge 等。

上面的第一种情况可能很适合我的 C++ 想法。主 *.cpp 文件可能在其中定义了一些类 NodeGraphEdge。但据我所知,这似乎确实没有抓住 C++ 的要点。我只是将我在 Java 中编写的内容强制放入 C++ 中,在适当的地方添加析构函数并将对象引用转换为指针。我还没有用 C++ 来思考。这些类是否需要分成单独的 *.cpp 文件?是否应该将它们分开,然后编译为库以在主程序中使用?我真正需要的是一些好的资源或人为的示例(甚至是经验法则)来说明,在 C++ 编程中,存在哪些不同的选项,以及什么时候考虑其中一个是一个好主意?


编辑:@Pawel Zubrycki 要求我提供一些示例代码。我不打算这样做,因为每个组件都相当琐碎 - 它通常有对下一事物的引用,以及一些 get/set 方法。不过,我将描述它。

它本质上是一个事件列表。有一些不必要的使用称为 ...Pointer 的类 - 它们是最初用于向我解释发生率列表的图表的直译产物。

有一个容器类 VertexList,它包含一个头元素 VertexPointer,以及添加新 VertexPointer 对象的方法(将其添加到图形中,但不将其连接到任何其他节点,从而允许搜索搜索非连接图),对 Vertex 对象上的索引进行简单搜索等。每个 VertexPointer 都有一个 Vertex 对象,以及 VertexPointer next; 以及您可能期望的所有方便的 hasNext() 方法。 Vertex 也有一个关联的 ConnectionList

EdgeListEdgePointerEdge< 也是如此。 /code>,但 Edge 与两个 Connection 对象关联。

ConnectionListConnectionConnectionList 模仿 VertexListEdgeList,具有 连接头; 以及您可能期望的所有便捷方法,例如 addConnection()。一个Connection有一个与之关联的Edge,以及一些Connection next;

这使我们能够轻松获得任意一点的连通分量在图中,并且有任意数量的连接。


它看起来非常复杂,但是可以使用 Vertex 对象的一些 LinkedList 来复制相同的功能,LinkedList>Edge 对象,以及许多 LinkedListConnection 对象。 Vertex 对象的 LinkedList 允许我们迭代所有顶点以对顶点进行穷举搜索,这同样适用于边。 ConnectionLinkedList 对象允许我们快速遍历到任何连接的顶点,并在图中任意添加或连接。添加这一复杂性步骤是为了处理评估图的某种着色的复杂性(加权边、局部子图的快速遍历等)

In my spare time, I've been taking code I've written for various purposes and appropriating them into other languages just to have a look at what's out there. Currently I'm taking a genetic programming graph colouring algorithm, originally written in Java, and trying to coerce it into C++.

The arbitrary data structure I'm using for the task has a few classes. In Java, it wasn't so much of an issue for me because I had been exposed to it for a while. The graph structure was only created once, and a Colouring was assigned to that. The Colouring (specifically finding a mostly optimal one) was the real point of the code. I could have a Graph class with inner classes like Node and Edge, for instance, or I could have a package graph with classes Graph, Node, Edge, etc.

The first case above might lend itself well to my idea of C++. A main *.cpp file might have some classes Node, Graph, Edge, defined in it. But this seems to really be missing the point of C++, from what I can tell. I'm just taking what I wrote in Java and forcing it into C++, adding destructors where appropriate and turning object references to pointers. I'm not yet thinking in C++. Do these classes bear separating into separate *.cpp files? Should they be separated, and then compiled as a library to use in the main program? What I really need are some good resources or contrived examples (or even rules of thumb) to say, in C++ programming, what are the different options that exist and when is it a good idea to thinking about one over the other?


EDIT: I've been asked by @Pawel Zubrycki to provide some example code. I'm not going to do this, because each component is fairly trivial - It generally has a reference to the next thing, and some get/set methods. I will, however, describe it.

It's essentially an incidence list. There is some unnecessary use of classes termed ...Pointer - they were a product of a literal translation of a diagram first used to explain incidence lists to me.

There is a container class, VertexList, which contains a head element VertexPointer, and methods to add new VertexPointer objects (Adding it to the graph, but not connecting it to any other nodes, allowing searches to search non-connected graphs), naive search for indices on Vertex objects, etc. Every VertexPointer has a Vertex object, as well as a VertexPointer next;, and all those handy hasNext() methods that you might expect. A Vertex also has an associated ConnectionList

The same is duplicated for EdgeList, EdgePointer, and Edge, except that an Edge is associated with two Connection objects.

ConnectionList and Connection: ConnectionList mimicking VertexList or EdgeList, having a Connection head; and all those handy methods you might expect, like addConnection(). A Connection has an Edge associated with it, as well as some Connection next;

This allows us to easily get the connected components of any one point in the graph, and have an arbitrary number of connections.


It seems pretty over-the-top complicated, but the same functionality could be duplicated with some LinkedList of Vertex objects, a LinkedList of Edge objects, and a number of LinkedList of Connection objects. The LinkedList of Vertex Objects allows us to iterate over all Vertices for exhaustive searches on Vertices, and the same applies for edges. The LinkedList objects of Connection allow us to quickly traverse to any connected Vertices and to arbitrarily add or connections in the graph. This step up in complexity was added to deal with the complexity of evaluating a certain colouring of a graph (weighted edges, quick traversal of local subgraphs, etc.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心房的律动 2024-10-15 07:07:23

如果您有像 NodeGraphEdge 这样的类,并且它们的实现不是太大,那么将它们定义在一个类中是非常有意义的和相同的 .cpp 文件。毕竟,它们是要一起使用的。

在C++中,像这样的包称为组件。通常,在组件中思考比在类中思考更有意义,因为 C++ 不仅是一种 OOP 语言,而且类并不总是首选的处理方式。

如果您想了解有关用 C++ 组织代码的首选方式的更多信息,我建议 Large Scale C++ 软件设计

顺便说一句:用这些类创建一个库确实看起来有点矫枉过正。

If you have classes like Node, Graph and Edge, and their implementation is not too large, it makes perfectly good sense to define them in one and the same .cpp file. After all, they are meant to be used together.

In C++, a package like this is called a component. Usually it makes more sense to think in components than classes, since C++ is not only an OOP language and classes are not always the preferred way do things.

If you want to learn more about the preferred way to organize code in C++, I recommend Large Scale C++ Software Design.

BTW: Making a library out of these classes really seems overkill.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文