Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
Я не улыбаюсь.
-8 / 1 / 0
Регистрация: 10.03.2020
Сообщений: 102

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

11.05.2020, 21:26. Показов 2569. Ответов 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
9005 / 4706 / 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
9005 / 4706 / 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
22.05.2020, 09:44
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я решил передать по значению зря.
Ну как раз std::initializer_list<T> обычно только по значению и передается. Само по себе его копирование не вызывает накладных расходов (там максимум будет 2 указателя внутри, глубокое копирование в этом классе не предусматривается), а компилятор вдовесок еще и точно знает как его оптимизировать.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.05.2020, 09:47
Цитата Сообщение от DrOffset Посмотреть сообщение
Ну как раз std::initializer_list<T> обычно только по значению и передается. Само по себе его копирование не вызывает накладных расходов (там максимум будет 2 указателя внутри, глубокое копирование в этом классе не предусматривается), а компилятор вдовесок еще и точно знает как его оптимизировать.
Я примерно так и решил понадеявшись на то, что реализация мувсеманная (пардон за оборотец). Но не доделал сам код после изменения параметра. А по константной ссылке и с константным преобразованием оно всё же лучше (имхо).
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
22.05.2020, 09:56
Цитата Сообщение от IGPIGP Посмотреть сообщение
А по константной ссылке и с константным преобразованием оно всё же лучше (имхо).
Нет, в данном случае не лучше. В некоторых случаях может быть даже медленнее из-за дополнительной косвенности.
std::initializer_list при использовании по прямому назначению всегда лучше передавать по значению. Это тип со ссылочной семантикой, он для этого и разработан.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru