Я не улыбаюсь.
-8 / 1 / 0
Регистрация: 10.03.2020
Сообщений: 102

Массив указателей на объекты наследуемых классов

11.05.2020, 21:26. Показов 2748. Ответов 29

Студворк — интернет-сервис помощи студентам
Добрый день!

Класс Patircle по задаче должен быть абстрактным, у него два наследника. В задаче сказано "В программе должен быть определён основной класс система, содержащий массив указателей на объекты-частицы".
Пожалуйста, посмотрите ниже по тексту, направляю вам часть программы.

Вопросы:

1. Проверьте пожалуйста правильно ли я написал класс System?
2. Если я буду использовать std::vector<Particle*> particles; как #include <vector> облегчит мне жизнь?
Никогда им не пользовался.
3. Как реализовывается доступ к объектам-частицам(наследуемых классов) через указатель(Particle*) на базовый(абстрактный класс)? Буду рад почитать литературу на эту тему.

Может быть вы еще что то заметите.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Particle {
protected:
    double x, y;
    double vx, vy;
    double radius;
public:
    Particle() : Particle(0, 0, 0, 0, 0) {}
    Particle(double ax, double ay, double avx, double avy, double aradius)
         : x(ax), y(ay), vx(avx), vy(avy), radius(aradius) {}
    virtual ~Particle() {}
    
    //virtual void Collision() = 0;
 
    void Move(time) {
        x += vx * time;
        y += vy * time;
    };
 
};
 
class System {
private:
    // unsigned time;
    // std::vector<Particle*> particles;
    Particle* particles;
    unsigned size;
    unsigned elems;
    static const unsigned defaultSize;
public:
    System() : System(defaultSize) {}
    System(unsigned asize) : elems(0) {
        if(asize < defaultSize)
            asize = defaultSize;
        size = asize;
        particles = new (Particle*)[size] {};
    }
    System(const System& obj) {
        size = obj.size;
        elems = obj.elems;
        particles = new (Particle*)[size] {};
        for( ; particles != NULL ; particles++)
            (*particles) = obj.*particles;
    }
    ~System() { delete[] particles; }
 
    //void add();
    //void delet();
};
const unsigned System::defaultSize = 8;
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.05.2020, 21:26
Ответы с готовыми решениями:

Как понять: массив указателей на объекты классов?
если приведете пример буду рад.

Абстрактный класс, массив указателей на объекты производных классов
У меня есть абстрактный класс: class abstract{ public: int field; double method(); }; В нем объявлены поле и метод. Далее...

Виртуальные функции (создать массив указателей на объекты трех классов)
Задание: создать массив указателей на объекты трех классов. Метод Show почему-то не переопределяется. В данном коде вводится 3 элемента в...

29
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
22.05.2020, 01:24
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Glbvnts Посмотреть сообщение
particles.push_back(std::move( const_cast<std::unique_ptr<Par ticle>&>(elem)));
Этот блок целиком неправильный.
Должно быть так:
C++
1
2
3
4
5
6
    System(std::initializer_list<std::unique_ptr<Particle>> alist) {
        particles.reserve(alist.size());
        for (auto& elem : alist) {
            particles.push_back(std::move(elem));
        }
    }
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.05.2020, 01:36
Цитата Сообщение от Glbvnts Посмотреть сообщение
происходит что то такое?
В общем да. Но обычно сравнению на < предпочитают !=. Итераторы вектора или массива могут сравниваться, а списка - нет, поэтому для общности лучше
C++
1
for (auto ptr = begin; ptr != end; ++ptr)
Получать начало и конец можно так:
C++
1
auto it=particles.begin();
Цитата Сообщение от Glbvnts Посмотреть сообщение
читал, что он обладает таким свойством благодаря &, то есть это позволяет не создавать копии. не совсем понимаю копии чего?
себя. Потом что:
Цитата Сообщение от Glbvnts Посмотреть сообщение
unique_ptr полностью должен полностью владеть переданным ему объектом, поэтому этот указатель после перемещения не будет владеть частицой(nullptr скорее всего).
Да. Должен остаться только один (с). Владение передаётся а отдавшая рука не усыхает. В ней остаётся nullptr. То есть, то что народ получил от приватизации (политкорректно выражаясь)
Цитата Сообщение от Glbvnts Посмотреть сообщение
здесь резервируется место(память???), но не выделяется память под указатели.
под них и выделяется. А под целевые объекты указателей не выделяется. reserve помогает сразу создать ящера нужной длины. Тогда он не будет реалоцироваться делая системные вызовы на выделение как укушенный в allocator.
Цитата Сообщение от Glbvnts Посмотреть сообщение
На чатицу у нас будет ссылка, как "ссылка r-value". Вы это имеете в виду?
нет. Ссылка тут с другого боку. Мув вызывается сам на rvalue ссылках. Компилятор чувствуя мертвечину -перемещает душу в новое тело. А поэтому lvalue нужно явно привести к rvalue явным вызовом std::move.
Glbvnts, я не могу ответить на 100 вопросов. Лучше в одном посте 1-2. К тому же другим, это читать совершенно не в жилу. Давайте по кусочку разбирать.
Но в принципе, это не верно с методологической (правильной пацанской) точки зрения, учить за день, в боевом режиме то, на что отводятся месяцы. Толку не будет. Почти. Я закругляюсь, так как вижу что вы продолжаете дописывать вопросы.
Давайте по одному. Но более менее обстоятельно. Ок?
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.05.2020, 09:36
Цитата Сообщение от DrOffset Посмотреть сообщение
C++
1
particles.push_back(std::move( const_cast<std::unique_ptr<Par ticle>&>(elem)));
Этот блок целиком неправильный.
Это верно. Вначале параметр объявлялся константной ссылкой. Прототип кода мною найден в сети (что редко но бывает ) и он не вызывал особых сомнений:
C++
1
2
3
4
5
6
7
8
9
template<typename T>
std::vector<T> vector_from(const std::initializer_list<T>& il)
{
  std::vector<T> result;
  result.reserve(il.size());
  for (const auto& e : il)
    result.push_back(std::move(const_cast<T&>(e)));
  return result;
}
Я решил передать по значению зря. И константное преобразование не убрал. Не аккуратно вышло, - согласен. Времени не было а кода больше страницы.
Написал плохо:
C++
1
2
3
4
5
6
7
8
9
template<typename T>
std::vector<T> vector_from(std::initializer_list<T> il)
{
  std::vector<T> result;
  result.reserve(il.size());
  for (auto& e : il)
    result.push_back(std::move(const_cast<T&>(e)));
  return result;
}
а ТС лишь пытался улучшить, за что ему +1. Пытается налету соображать)
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
22.05.2020, 09:44
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я решил передать по значению зря.
Ну как раз std::initializer_list<T> обычно только по значению и передается. Само по себе его копирование не вызывает накладных расходов (там максимум будет 2 указателя внутри, глубокое копирование в этом классе не предусматривается), а компилятор вдовесок еще и точно знает как его оптимизировать.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.05.2020, 09:47
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну как раз std::initializer_list<T> обычно только по значению и передается. Само по себе его копирование не вызывает накладных расходов (там максимум будет 2 указателя внутри, глубокое копирование в этом классе не предусматривается), а компилятор вдовесок еще и точно знает как его оптимизировать.
Я примерно так и решил понадеявшись на то, что реализация мувсеманная (пардон за оборотец). Но не доделал сам код после изменения параметра. А по константной ссылке и с константным преобразованием оно всё же лучше (имхо).
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
22.05.2020, 09:56
Цитата Сообщение от IGPIGP Посмотреть сообщение
А по константной ссылке и с константным преобразованием оно всё же лучше (имхо).
Нет, в данном случае не лучше. В некоторых случаях может быть даже медленнее из-за дополнительной косвенности.
std::initializer_list при использовании по прямому назначению всегда лучше передавать по значению. Это тип со ссылочной семантикой, он для этого и разработан.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.05.2020, 10:24
Цитата Сообщение от DrOffset Посмотреть сообщение
Нет, в данном случае не лучше.
Не спорю. Не читал гарантирует ли реализация поверхностное копирование)
0
Я не улыбаюсь.
-8 / 1 / 0
Регистрация: 10.03.2020
Сообщений: 102
22.05.2020, 14:15  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Должно быть так:
так не работает

In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/string:41,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from /home/ivantsov/cpp/task2.cpp:1:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct (_Up*, _Args&& ...) [with _Up = std::unique_ptr<Particle>; _Args = {const std::unique_ptr<Particle, std::default_delete<Particle> >&}; _Tp = std::unique_ptr<Particle>]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_Ch arT> >::construct(std::allocator_traits<std:: allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::unique_ptr<Particle>; _Args = {const std::unique_ptr<Particle, std::default_delete<Particle> >&}; _Tp = std::unique_ptr<Particle>; std::allocator_traits<std::allocator<_Ch arT> >::allocator_type = std::allocator<std::unique_ptr<Particle> >]’
/usr/include/c++/7/bits/stl_vector.h:943:30: required from ‘void std::vector<_Tp, _Alloc>:ush_back(const value_type&) [with _Tp = std::unique_ptr<Particle>; _Alloc = std::allocator<std::unique_ptr<Particle> >; std::vector<_Tp, _Alloc>::value_type = std::unique_ptr<Particle>]’
/home/ivantsov/cpp/task2.cpp:63:91: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Particle; _Dp = std::default_delete<Particle>]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/memory:80:0,
from /home/ivantsov/cpp/task2.cpp:3:
/usr/include/c++/7/bits/unique_ptr.h:383:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
22.05.2020, 21:54
Цитата Сообщение от Glbvnts Посмотреть сообщение
так не работает
Верно, есть такое дело.
У std::initializer_list есть только константные begin\end, я что-то позабыл этот момент, отвлёкшись на константность ссылки в примере.
Поэтому в целом std::initializer_list на данном этапе в принципе не приспособлен, чтобы оперировать move-only типами, такими как unique_ptr. Досадно, но факт.
Если вы хотите оставить этот вариант, то хак с сonst_cast - не то, чтобы правильно, но один из немногих способов этого добиться. Второй способ использовать идиому in (что тоже в некотором роде хак, но более изощренный).

Если интересно, есть вот такое предложение, для исправления этой ситуации: http://open-std.org/jtc1/sc22/... /n4166.pdf, в идеале нечто подобное могло бы обеспечить наиболее правильное решение.
0
Я не улыбаюсь.
-8 / 1 / 0
Регистрация: 10.03.2020
Сообщений: 102
23.05.2020, 00:00  [ТС]
DrOffset, спасибо, буду разибираться. Хотя так и хочется задать глупые вопросы

Добавлено через 43 секунды
Цитата Сообщение от IGPIGP Посмотреть сообщение
Но более менее обстоятельно. Ок?
Хорошо, спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.05.2020, 00:00
Помогаю со студенческими работами здесь

Из трех наследуемых классов получить массив родителя
Всем мира! Не один раз вы меня выручали, помогите, пожалуйста и в этот раз. Расту. И вопросы становятся глобальней. В общем, нашел такую...

Массив указателей на объекты
Доброго времени суток. В моем коде базовый класс имеет два наследника. Четвертый класс содержит динамический массив указателей на...

Динамический массив указателей на объекты
вообщем была тут на форуме задача, в подробности вдаваться не буду, смысл сейчас заключается в том, чтобы создавать в цикле объекты, и в их...

Массив указателей на объекты подклассов
Доброго времени суток всем!!! Проф задал написать парсер простых математических выражений с использованием скобок. Код не должен...

Динамический массив указателей на объекты класса
Добрый вечер! Нужна помощь У меня имеется класс STROKA(вроде уже готовый,и все хорошо) Только вот никак не могу понять, как создать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

Новые блоги и статьи
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru