Say I have
Animal animals[100];
And now, at run-time, I want to initialize one of these to be a new instance of Cat, a subclass of Animal. How do I do this? I thought maybe I could do
animals[0] = Cat("Fluffy")
but this doesn't seem to work. My understanding of how a constructor works in C++ is that space for the object is allocated, and then a pointer to that space is passed to the constructor function (as this). In particular, the constructor works even if that space contains any arbitrary garbage data. So it seems to me that even if animals[0] already contains data initialized by the constructor of Animal or whatever else was occupying that slot beforehand, it should be possible to just call the constructor of Cat on that space and have it work exactly as if it were a totally "fresh" object. How can I achieve this?
For example, the following code should print "Fluffy", but it prints "Anonymous".
#include <stdio.h>
class Animal
{
public:
virtual char const *get_name() { return "Anonymous"; };
};
class Cat : public Animal
{
char const *name;
public:
Cat(char const *name) { this->name = name; }
char const *get_name() { return name; }
};
Animal animals[100];
int main()
{
animals[0] = Cat("Fluffy");
printf("%s\n", animals[0].get_name());
return 0;
}
animals[0] = Cat("Fluffy")callsAnimal::operator=(const Animal&). stackoverflow.com/questions/274626/what-is-object-slicing Generally if you want a heterogeneous array you would need to store pointers to the base class, or preferably a smart pointer, e.g.std::unique_ptr<Animal> animals[100];,animals[0] = std::make_unique<Cat>("Fluffy"). You could also use something likestd::variant.namepointer, but Animal does not, so a Cat will not fit in space that was allocated only for an Animal. You will either need indirection provided by a pointer, or some kind of union (ensuring enough space is available; std::variant can do this, or std::aligned_union + placement new for a no-batteries-included approach). If you're storing multiple classes derived from the same base, a union will not allow you to use the common base interface, while a pointer will.Animalis compiled say only onlyCatandDogexist as subclasses. A while later,Wombatis added in a third-party library. There's no way forAnimalto know of this new subclass. Because of thisAnimalonly knowsAnimal. All derived classes are unknown.