C++ changing type in constructor?

c++, class, polymorphism, types

Solution

It sounds like you would want to use abstract factory pattern to instantiate your objects so that you would not have to directly call constructors of the concrete classes. Then, in case you would want to change the concrete types that implement your interfaces, you would only need to either link in a different implementation of your abstracy factory, or select a proper factory implementation at run time.

Edit: Missed the "don't want to use factory"... Anyway you will need some kind of redirection, because constructor will return the type you instantiate. Closest you can get is probably creating a static factory method "create" to class Vector3D that returns a pointer to Vector3D, but internally creates an instance of concrete implementation class. In case you do that, it is good practice to make the constructor of Vector3D private to prevent creating the vector in "wrong way".

Problem

I have an abstract class `Engine3D` and it's structures (`Vector3D`, etc.) in the header files. Now, I have an implementation for that class, `ConcreteEngine3D : Engine3D`. Also, I have other classes like `ConcreteVector3D : Vector3D` that have additional members and methods that will be used inside `ConcreteEngine3D` (for the sake of this example, let's say it's `float length` and `calculateLength()`). In main.cpp I have the code: ``` #include "ConcreteEngine3D.h" Engine3D * engine; ... int main(){ engine = new ConcreteEngine3D(); Vector3D* vector = new Vector3D(engine, 10, 5, 2); } ``` I want the variable `vector` be of type `ConcreteVector3D*`. I will need that type in `ConcreteEngine3D`, but in main.cpp I shouldn't even know it's that type and don't have to use extended fields like `length`. Also, I can't use in main.cpp anything specifically from ConcreteEngine3D.h (only Engine3D.h) - it's for the flexibly, changing the implementation must means only changing the inclusion and line with `new ConcreteEngine3D()`. I do not want to modify that code above or original headers from `Engine3D`. In the constructor of `Vector3D` I always put a pointer to `Engine3D` object (and I give here `ConcreteEngine3D` type). Maybe can I do something in the constructor of `Vector3D` to change the type of it? For example call `Vector3D* Engine3D::convert(Vector3D v)` inside of the constructor which will be inherited from `Engine3D` in `ConcreteEngine3D` (which creates a new `ConcreteVector3D` object with fields from `Vector3D` and returns it). Of course that code doesn't work: ``` Vector3D::Vector3D(Engine3D *engine){ //how to 'return' or 'convert' the type to the one that returns engine->convert(this); } ``` So basically, I want to get the effect of code below but without the line `vector = engine->convert(vector)` or `Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2)`. ``` #include "ConcreteEngine3D.h" Engine3D * engine; ... int main(){ engine = new ConcreteEngine3D(); Vector3D* vector = new Vector3D(engine, 10, 5, 2); //produces Vector3D, not ConcreteVector3D vector = engine->convert(vector); //cannot be here! but creates the right object Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2); //also creates rights object, but cannot be here! } ``` Also, I don't want to use factory in `Engine3D` or `ConcreteEngine3D`. I want to allow the 'user' create `Vector3D` just the way I have written in the first code.

Original source