c++ - 如何正确管理空指针 vector

标签 c++ memory-management vector void-pointers

首先,一些背景:

我正在做一个项目,它要求我模拟可以被认为是多边形(通常是三角形或四边形,几乎肯定少于七条边)的对象之间的交互,每条边的半径为 2具有可变(可能为零)数量的各种恒定宽度的“河流”的圆圈在它们之间通过,并通过另一侧从多边形出来。由于这些河流和圆圈及其宽度(以及圆圈的位置)是在运行时指定的,因此这些具有 N 条边和 M 条河流穿过它的多边形之一可以完全用一个 N+2M 指针数组来描述,每个指针指向相关的河流/圆圈,从多边形的任意角开始并绕过(原则上,由于河流不能重叠,它们应该可以用较少的数据指定,但实际上我不确定如何实现)。

我最初是用 Python 编写的,但很快发现对于更复杂的安排,性能慢得令人无法接受。在将其移植到 C++ 时(选择它是因为它的可移植性和与 SDL 的兼容性,一旦优化完成我将使用它来呈现结果)我对如何处理多边形结构有些不知所措。

显而易见的事情是为它们创建一个类,但是由于 C++ 甚至缺少运行时大小的数组或多类型数组,唯一的方法是使用一组非常麻烦的 vector 来描述列表圆圈、河流和它们的相对位置,或者某种更加繁琐的“边缘”类。而不是这样,似乎更好的选择是使用一个更简单但仍然令人讨厌的空指针 vector ,每个指针都指向河流/圆圈,如上所述。

现在,问题:

如果我是正确的,那么处理相关内存分配的正确方法应该是这样的,并尽量减少困惑(不多说......):

int doStuffWithPolygons(){
    std::vector<std::vector<void *>> polygons;
    while(/*some circles aren't assigned a polygon*/){
        std::vector<void *> polygon;
        void *start = &/*next circle that has not yet been assigned a polygon*/;
        void *lastcircle = start;
        void *nextcircle;
        nextcircle = &/*next circle to put into the polygon*/;
        while(nextcircle != start){
            polygon.push_back(lastcircle);
            std::vector<River *> rivers = /*list of rivers between last circle and next circle*/;
            for(unsigned i = 0; i < rivers.size(); i++){
                polygon.push_back(rivers[i]);
            }
            lastcircle = nextcircle;
            nextcircle = &/*next circle to put into the polygon*/;
        }
        polygons.push_back(polygon);
    }

    int score = 0;
    //do whatever you're going to do to evaluate the polygons here
    return score;
}

int main(){
    int bestscore = 0;
    std::vector<int> bestarrangement; //contains position of each circle
    std::vector<int> currentarrangement = /*whatever arbitrary starting arrangement is appropriate*/;
    while(/*not done evaluating polygon configurations*/){
        //fiddle with current arrangement a bit
        int currentscore = doStuffWithPolygons();
        if(currentscore > bestscore){
            bestscore = currentscore;
            bestarrangement = currentarrangement;
        }
    }

    //somehow report what the best arrangement is

    return 0;
}

如果我正确理解这些东西是如何处理的,我就不需要任何 delete 或 .clear() 调用,因为函数调用后一切都超出了范围。我对此是否正确?另外,上面是否有任何部分不必要地复杂,或者不够复杂?我是否认为这就像 C++ 允许我实现的一样简单,或者是否有某种方法可以避免某些迂回构造?

如果您的回答是“不要使用空指针”或“只创建一个多边形类”,除非您能解释它如何使问题更简单 ,省去麻烦。我是唯一一个会看到这段代码的人,所以我不在乎是否遵循最佳实践。如果我忘记了我是如何/为什么做某事并且后来给我带来了问题,那是我自己没有充分记录它的错,而不是我以不同的方式编写它的理由。

编辑 由于至少有人问过,这是我原来的 python,处理流程的多边形创建/评估部分:

#lots of setup stuff, such as the Circle and River classes

def evaluateArrangement(circles, rivers, tree, arrangement): #circles, rivers contain all the circles, rivers to be placed. tree is a class describing which rivers go between which circles, unrelated to the problem at hand. arrangement contains (x,y) position of the circles in the current arrangement.
    polygons = []
    unassignedCircles = range(len(circles))
    while unassignedCircles:
        polygon = []
        start = unassignedCircles[0]
        lastcircle = start
        lastlastcircle = start
        nextcircle = getNearest(start,arrangement)
        unassignedCircles.pop(start)
        unassignedCircles.pop(nextcircle)
        while(not nextcircle = start):
            polygon += [lastcircle]
            polygon += getRiversBetween(tree, lastcircle,nextcircle)
            lastlastcircle = lastcircle
            lastcircle = nextcircle;
            nextcircle = getNearest(lastcircle,arrangement,lastlastcircle) #the last argument here guarantees that the new nextcircle is not the same as the last lastcircle, which it otherwise would have been guaranteed to be.
            unassignedCircles.pop(nextcircle)
        polygons += [polygon]
    return EvaluatePolygons(polygons,circles,rivers) #defined outside.

最佳答案

作为模板参数的 Void 必须是小写的。除此之外它应该可以工作,但我也建议为此使用一个基类。使用智能指针,您可以让系统处理所有内存管理。

关于c++ - 如何正确管理空指针 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32918854/

相关文章:

c++ - ExtTextOut 文本不断闪烁,并且在设定的时间后文本恢复为默认字体

c++ - 为什么异常时不调用析构函数?

c++ - 为什么 std::shared_ptr 起作用?

java - 创建的对象数量

arrays - 将字符串添加到空数组给出 `NAN`

c++ - 多字节西里尔字母表

objective-c - 保留/释放保留属性的合成 Setter

c++ - 将元素添加到未存储的 c++ 类中的 vector

c# - "Type is not expected, and no contract can be inferred: Leap.Vector"错误。使用 Protobuf-net 序列化器

c++ - 在 OpenCV 中展开一组矩形以形成正方形网格