Tried searching, nothing returns( i ithink).
Is it possible to make a vector of an abstract class?
For example, I have the super class Unit.
And I Ha
You cannot literally create a vector of objects of an abstract class, because the vector template needs to be able to tell the compiler, at compile time, the size of its element. However, you can get what you want by keeping a vector of pointers to objects rather than a vector of objects as such.
Update: Abstract classes as such have known size. It is actually instances of their most derived types whose sizes are unknown at compile time. (Thanks @LuchianGrigore and @MooingDuck for pointing this out.)
Yes, but you'll need to use either pointers or smart pointers (I'd go with this).
struct X
{
virtual ~X() {} //<--- as pointed out in the comments
// a virtual destructor is required
// for correct deletion
virtual void foo() = 0;
};
struct Y : X
{
virtual void foo() { }
};
int main()
{
std::vector<X*> a;
a.push_back(new Y);
a[0]->foo();
for ( int i = 0 ; i < a.size() ; i++ )
delete a[i];
return 0;
}
Don't forget to delete the allocated memory.
Assume std::vector<X>
. This is illegal because:
If you want to initialize your vector with some number of elements, the allocation would fail. A vector stores objects internally in continuous memory. A preallocation would fail because it would mean it needed to create objects, which can't be done for abstract classes.
Even if you could, or the base class wasn't abstract, it wouldn't help too much, as you'd suffer from object slicing.
I don't think it's possible to do this:
std::vector<Unit> unit_list;
unit_list.push_back(Soldier(params));
Because Soldier, Vehicle, and Unit take up different amounts of memory.
However, it might be possible to use pointers, as all pointers take up a fixed amount of memory:
std::vector<Unit*> unit_list;
unit_list.push_back(new Soldier(params));
I haven't tested it, but it makes sense in my head anyway.
Since each of those objects is different sizes, the proper way to do this is a container containing pointers to the base class Unit
, (and be sure it has a virtual
destructor.
Option 1: boost::ptr_vector (requires boost libraries, which you should have anyway)
ptr_vector<Unit> units;
units.push_back(new Soldier());
Option 2: std::vector<std::unique_ptr<Unit>>
(requires C++11 compiler)
std::vector<std::unique_ptr<Unit>> units;
units.emplace_back(std::unique_ptr<Unit>(new Soldier()));