A constructor's job is to turn some bit of memory into a valid object of its type.
This means that someone (the C++ runtime via incrementing the stack pointer, calling ::operator new or even you yourself when placement new is used) had to provide you with the amount of memory your class requires.
Therefore, there is no way of providing a constructor that constructs an arbitrary derived object, even if the language allowed this, since the derived object may require more memory!
What you can do however is to write a factory method, that uses new
to allocate a fitting amount of dynamic memory and construct your object into it. A factory method is just an ordinary method that returns a pointer or reference to the created object, but for all intents and purposes works just like the constructor you described:
Base& factory(size_t type) {
if(1 == type) return *static_cast<Base*>(new Derived1());
if(2 == type) return *static_cast<Base*>(new Derived2());
throw "You should define what happens in this case!";
}
Base& x = factory(1);
delete &x;
When dealing with a factory that creates objects with dynamic storage duration, it is often advisable to not return a reference but to return an object that ensures your object will be properly destroyed:
shared_ptr<Base> factory(size_t type) {
if(1 == type) return shared_ptr<Base>(new Derived1());
if(2 == type) return shared_ptr<Base>(new Derived1());
throw "You should define what happens in this case!";
}
auto test = factory(1);
One final warning: When you only retain a pointer to a base of an object, like here, the base class should have a virtual destructor.