#c #pointers #vector
#c #указатели #вектор
Вопрос:
Я все еще пытаюсь понять, что я хочу сделать. Мой код должен принимать определенные пользователем сегменты (например, линию, круг или любое другое определение геометрического сегмента, которое я буду реализовывать) и объединять их в вектор. Однако порядок типов сегментов («линия», «круг», …) определяется пользователем и, следовательно, может варьироваться от выполнения к выполнению.
Прежде чем я продолжу: каждый сегмент имеет разные входные данные, необходимые для его собственного создания (например, линия не имеет радиуса, только начальная и конечная точки).
Мой предпочтительный подход был бы
- прочитайте пользовательский ввод и определите порядок сегментов
- создайте каждый сегмент
- Передайте их функции (например, функции-члену / методу для класса, реализующего контур).
- Эта функция создает контур, например, путем реализации вектора.
Мой текущий тестовый код имеет жестко запрограммированную последовательность сегментов, но трюк, которого я хочу добиться, заключается в том, что порядок (и количество) сегментов не жестко запрограммированы. К сожалению, я не могу понять, как.
Вот код:
#include <iostream>
#include <vector>
struct point
{
double x;
double y;
};
class segment
{
public:
segment()
{
P1.x = 0;
P1.y = 0;
P2.x = 0;
P2.y = 0;
};
virtual ~segment() {};
virtual double get_radius() { return 0; };
virtual double get_length() { return 0; };
virtual double get_angle() { return 0; };
int segment_id = 0;
protected:
point P1;
point P2;
};
class Line : public segment
{
public:
Line() {};
Line(const point pt1, const point pt2)
{
P1.x = pt1.x;
P1.y = pt1.y;
P2.x = pt2.x;
P2.y = pt2.y;
segment_id = 1;
};
~Line() {};
double get_length() { return calc_length(); };
double get_angle() { return calc_angle(); };
private:
double calc_length()
{
// calculate length (here: dummy value)
return 1;
}
double calc_angle()
{
// calculate angle (here: dummy value)
return 0.5;
}
double length = 0;
double angle = 0;
}
;
class circle : public segment
{
public:
circle()
{
center.x = 0;
center.y = 0;
};
circle(const double r, const point c)
{
radius = r;
center.x = c.x;
center.y = c.y;
segment_id = 2;
};
~circle() {};
double get_radius() { return radius; };
point get_center() { return center; };
double get_length() { return 3.14 * radius; }; //returns circumference
private:
double radius = 0;
point center;
};
//-------------------------------------------------------
int main()
{
int nbr = 5;
point start;
start.x = 1;
start.y = 2;
point end;
end.x = 3;
end.y = 4;
point c;
c.x = 0;
c.y = 0;
double r = 9;
auto anotherCircle = std::make_unique<circle>(r, c);
auto anotherLine = std::make_unique<Line>(start, end);
std::unique_ptr<circle> yet_anotherCircle;
circle* myCircle = new circle(r, c);
Line* myLine = new Line(start, end);
//VERSION 1: Does not compile. I get an exception in <memory> line 1762 when trying to delete _Ptr
//std::vector<std::unique_ptr<segment>> v1;
//v1.emplace_back(anotherCircle);
//v1.emplace_back(anotherLine);
//std::cout << v1[0]->get_radius() << std::endl;
//v1.emplace_back(myLine);
//std::cout << v1[1]->segment_id << std::endl;
//VERSION 2: Compiles
std::vector<std::unique_ptr<segment>> v2;
v2.emplace_back(std::make_unique<circle>(r, c));
v2.emplace_back(std::make_unique<Line>(start, end));
}
Прямой способ, который я себе представляю, но который, похоже, не работает, потребует работы версии 1. Тогда я мог бы, вероятно, использовать объекты шаблона, которые я передаю в вектор. К сожалению, это не тот путь, и я не имею ни малейшего представления, как к этому подойти. Было бы здорово, если бы кто-нибудь мог мне здесь помочь! Спасибо!
Ответ №1:
Вам нужно перемещать элементы в векторе, так как ваши элементы не могут быть скопированы:
v1.emplace_back(std::move(anotherCircle));
Комментарии:
1. Вау! ЭТО РАБОТАЕТ! Спасибо! Я два дня бился над этим вопросом, и вы решили его для меня менее чем за пять минут. К сожалению, я могу проголосовать только один раз.