Сначала немного:Как правильно управлять вектором пустых указателей
Я работаю над проектом, который требует, чтобы я моделировать взаимодействия между объектами, которые можно рассматривать в качестве полигонов (обычно треугольников или четырехугольников , почти наверняка меньше семи сторон), каждая из которых состоит из радиуса двух кругов с переменным (и, возможно, нулевым) числом «рек» различной постоянной ширины, проходящей между ними, и из многоугольника через какой-то другой боковая сторона. Поскольку эти реки и круги и их ширина (и положения кругов) указаны во время выполнения, один из этих многоугольников с N сторонами и протекающими через него реками M может быть полностью описан массивом указателей N + 2M, каждый из которых ссылается на соответствующие реки/круги, начиная с произвольного угла многоугольника и проходящего вокруг (в принципе, поскольку реки не могут пересекаться, они должны быть уточнены с меньшим количеством данных, но на практике я не уверен, как это реализовать).
Я изначально программировал это на Python, но быстро обнаружил, что для более сложных мероприятий производительность была неприемлемо медленной. Перенесив это на C++ (выбранный из-за его переносимости и совместимости с SDL, который я использую для рендеринга результата после завершения оптимизации), я немного теряю, как иметь дело с структурой многоугольника.
Очевидное, что нужно сделать для них класс, но поскольку на C++ отсутствуют даже массивы времени выполнения или массивы с несколькими типами, единственный способ сделать это будет с нелепо громоздким набором векторов, описывающих список кругов, рек и их относительного размещения, или еще более громоздкий «краевой» класс. Вместо этого кажется, что лучшим вариантом является использование гораздо более простого, хотя и все еще раздражающего, вектора указателей пустот, каждый из которых указывает на реки/круги, как описано выше.
Теперь вопрос:
Если я правильно, надлежащим образом обрабатывать соответствующие распределения памяти здесь с минимальным количеством путаницы (не говоря много ...) что-то вроде этого:
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++ позволит мне это сделать, или есть способ избежать какой-либо конструкции кольцевой развязки?
И если вы ответ будет что-то вроде «не используют недействительные указатели» или «просто сделать класс многоугольник», если вы не можете объяснить, как это сделает проблему проще, сохранить себя беда. Я единственный, кто когда-либо увидит этот код, поэтому я не забочусь о том, чтобы придерживаться лучших практик. Если я забуду, как/почему я что-то сделал, и это вызывает у меня проблемы позже, это моя собственная ошибка для недостаточно документирования, а не повод написать это по-другому.
редактировать Так, по крайней мере один человек спросил, вот мой оригинальный питон, обработка части создания полигона/оценки процесса:
#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?Почему не вектор указателей какого-то базового класса с виртуальными методами? –
Если вы выделяете что-либо в куче, оно будет * не * освобождено, когда вы выйдете из области видимости. Вы должны обернуть его в какой-то объект менеджера, который выполняет итерацию, и 'delete' все, что вы выделили. Как правило, любой вызов распределения через 'new' должен быть освобожден через вызов' delete', когда вы закончите –
Вероятно, самая большая причина не использовать указатели void - это то, что вы отказываете компилятору в возможности ловить ошибки, которые вы могли бы сделать с назначением указателя. –