Хранение абстрактного типа в stl::vector C++ [дубликат]

106
25 марта 2022, 16:40
На этот вопрос уже даны ответы здесь:
Можно ли хранить объекты разных классов (производных одного абстрактного класса) в одном массиве или списке? (3 ответа)
Закрыт 2 года назад.

Пытаюсь хранить в контейнере абстрактный тип "Weapon", но возникает ошибка. Код:

class Ismth { // Абстрактный класс 
    virtual void draw() = 0;
};
class Weapon : public Ismth{ // Weapon наследуется от абстрактного класса. Без наследования ошибки не возникает
public:
    Weapon() = default;
    void draw() override {};
};
class Shotgun : public Weapon { // Конкретная реализация Weapon.
public:
    Shotgun() = default;
    void draw() override {}; // Именно тут я хочу реализовать draw() из Ismth
};
void main() {
  vector<Weapon> weapons;
  Shotgun weapon1;
  weapons.push_back(weapon1);
}

Подскажите, пожалуйста, в чем может быть проблема? Возможно, в таком случае нужно использовать не vector?

Выдаёт:

In file included from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33:0,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/allocator.h:46,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/string:41,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/locale_classes.h:40,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/ios_base.h:41,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/ios:42,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/ostream:38,
                 from D:/Libraries/SFML/include/SFML/System/Err.hpp:32,
                 from D:/Libraries/SFML/include/SFML/System.hpp:34,
                 from D:/Libraries/SFML/include/SFML/Audio.hpp:32,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\main.cpp:1:
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Weapon; _Args = {const Weapon&}; _Tp = Weapon]':
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/alloc_traits.h:475:4:   required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Weapon; _Args = {const Weapon&}; _Tp = Weapon; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<Weapon>]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_vector.h:943:30:   required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Weapon; _Alloc = std::allocator<Weapon>; std::vector<_Tp, _Alloc>::value_type = Weapon]'
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:112:34:   required from here
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/ext/new_allocator.h:136:4: error: invalid new-expression of abstract class type 'Weapon'
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\main.cpp:12:0:
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:31:7: note:   because the following virtual functions are pure within 'Weapon':
 class Weapon : virtual public Idrawable {
       ^~~~~~
In file included from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Object2D.h:11:0,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Poligon2D.h:8,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\main.cpp:8:
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Idrawable.h:12:18: note:     virtual void Idrawable::draw(sf::RenderWindow&)
     virtual void draw(sf::RenderWindow& window) = 0;
                  ^~~~
In file included from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_tempbuf.h:60:0,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_algo.h:62,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/algorithm:62,
                 from D:/Libraries/SFML/include/SFML/System/Utf.hpp:32,
                 from D:/Libraries/SFML/include/SFML/System/String.hpp:32,
                 from D:/Libraries/SFML/include/SFML/System.hpp:42,
                 from D:/Libraries/SFML/include/SFML/Audio.hpp:32,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\main.cpp:1:
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = Weapon; _Args = {Weapon}]':
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:83:18:   required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Weapon*>; _ForwardIterator = Weapon*; bool _TrivialValueTypes = false]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:134:15:   required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Weapon*>; _ForwardIterator = Weapon*]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:289:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<Weapon*>; _ForwardIterator = Weapon*; _Tp = Weapon]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:311:2:   required from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = Weapon*; _ForwardIterator = Weapon*; _Allocator = std::allocator<Weapon>]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/vector.tcc:426:6:   required from 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const Weapon&}; _Tp = Weapon; _Alloc = std::allocator<Weapon>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<Weapon*, std::vector<Weapon> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = Weapon*]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_vector.h:948:21:   required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Weapon; _Alloc = std::allocator<Weapon>; std::vector<_Tp, _Alloc>::value_type = Weapon]'
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:112:34:   required from here
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_construct.h:75:7: error: invalid new-expression of abstract class type 'Weapon'
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mingw32-make.exe[3]: *** [CMakeFiles\Pseudo3DEngine.dir\build.make:63: CMakeFiles/Pseudo3DEngine.dir/main.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
In file included from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33:0,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/allocator.h:46,
                 from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/vector:61,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Object2D.h:9,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:8,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.cpp:7:
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Weapon; _Args = {const Weapon&}; _Tp = Weapon]':
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/alloc_traits.h:475:4:   required from 'static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Weapon; _Args = {const Weapon&}; _Tp = Weapon; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<Weapon>]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_vector.h:943:30:   required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Weapon; _Alloc = std::allocator<Weapon>; std::vector<_Tp, _Alloc>::value_type = Weapon]'
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:112:34:   required from here
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/ext/new_allocator.h:136:4: error: invalid new-expression of abstract class type 'Weapon'
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.cpp:7:0:
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:31:7: note:   because the following virtual functions are pure within 'Weapon':
 class Weapon : virtual public Idrawable {
       ^~~~~~
In file included from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Object2D.h:11:0,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:8,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.cpp:7:
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Idrawable.h:12:18: note:     virtual void Idrawable::draw(sf::RenderWindow&)
     virtual void draw(sf::RenderWindow& window) = 0;
                  ^~~~
In file included from D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/vector:62:0,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Object2D.h:9,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:8,
                 from D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.cpp:7:
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = Weapon; _Args = {Weapon}]':
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:83:18:   required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Weapon*>; _ForwardIterator = Weapon*; bool _TrivialValueTypes = false]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:134:15:   required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Weapon*>; _ForwardIterator = Weapon*]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:289:37:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<Weapon*>; _ForwardIterator = Weapon*; _Tp = Weapon]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_uninitialized.h:311:2:   required from '_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = Weapon*; _ForwardIterator = Weapon*; _Allocator = std::allocator<Weapon>]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/vector.tcc:426:6:   required from 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const Weapon&}; _Tp = Weapon; _Alloc = std::allocator<Weapon>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<Weapon*, std::vector<Weapon> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = Weapon*]'
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_vector.h:948:21:   required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Weapon; _Alloc = std::allocator<Weapon>; std::vector<_Tp, _Alloc>::value_type = Weapon]'
D:\ivan\Study\C & C++\problems3_laptop2\Pseudo3DEngine\Camera.h:112:34:   required from here
D:/mingw64/lib/gcc/x86_64-w64-mingw32/7.3.0/include/c++/bits/stl_construct.h:75:7: error: invalid new-expression of abstract class type 'Weapon'
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mingw32-make.exe[3]: *** [CMakeFiles\Pseudo3DEngine.dir\build.make:105: CMakeFiles/Pseudo3DEngine.dir/Camera.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:72: CMakeFiles/Pseudo3DEngine.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:84: CMakeFiles/Pseudo3DEngine.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: Pseudo3DEngine] Error 2
Answer 1

А как вы себе представляете экземпляр абстрактного типа?...

Да даже если бы и можно было - то получали бы вы при хранении потомков срезку. Например, добавив потомку какой-нибудь int - он бы при сохранении срезался.

Так что лучше храните, например, указатели на Weapon.
Можно поиграться с reference_wrapper и хранить якобы ссылки, но это только лишние телодвижения и сложности без ощутимой выгоды.

READ ALSO
MySQL не записывает большой текст

MySQL не записывает большой текст

Текст (10 000+ символов) при записи в БД обрезается, записывается не весьТекст меньшего размера записывается полностью

145
Проблема с отображением символов в mysql

Проблема с отображением символов в mysql

Пишу бота ВК на pythonИспользую mysql

122
Сортировка в алфавитном порядке на JAVA+sqlite

Сортировка в алфавитном порядке на JAVA+sqlite

Есть кодКак его видоизменить, чтобы данные из sqlite выводились в алфавитном порядке от А до Я?

256