Can we make a class constructor virtual in C++ to create polymorphic objects? No. C++ being static typed (the purpose of RTTI is different) language, it is meaningless to the C++ compiler to create an object polymorphically. The compiler must be aware of the class type to create the object. In other words, what type of object to be created is a compile time decision from C++ compiler perspective. If we make constructor virtual, compiler flags an error. In fact except inline, no other keyword is allowed in the declaration of constructor.
In practical scenarios we would need to create a derived class object in a class hierarchy based on some input. Putting in other words, object creation and object type are tightly coupled which forces modifications to extended. The objective of virtual constructor is to decouple object creation from it’s type.
How can we create required type of object at runtime? For example, see the following sample program.
In the above sample, assume that the hierarchy Base, Derived1 and Derived2 are part of library code. The class User is utility class trying to make use of the hierarchy. The main function is consuming Base hierarchy functionality via User class.
The User class constructor is creating Derived1 object, always. If the User‘s consumer (the main in our case) needs Derived2 functionality, User needs to create “new Derived2()” and it forces recompilation. Recompiling is bad way of design, so we can opt for the following approach.
Before going into details, let us answer, who will dictate to create either of Derived1 or Derived2 object? Clearly, it is the consumer of User class. The User class can make use of if-else ladder to create either Derived1 or Derived2, as shown in the following sample,
The above code is *not* open for extension, an inflexible design. In simple words, if the library updates the Base class hierarchy with new class Derived3. How can the User class creates Derived3 object? One way is to update the if-else ladder that creates Derived3 object based on new input ID 3 as shown below,
The above modification forces the users of User class to recompile, bad (inflexible) design! And won’t close User class from further modifications due to Base extension.
The problem is with the creation of objects. Addition of new class to the hierarchy forcing dependents of User class to recompile. Can’t we delegate the action of creating objects to class hierarchy itself or to a function that behaves virtually? By delegating the object creation to class hierarchy (or to a static function) we can avoid the tight coupling between User and Base hierarchy. Enough theory, see the following code,
The User class is independent of object creation. It delegates that responsibility to Base, and provides an input in the form of ID. If the library adds new class Derived4, the library modifier will extend the if-else ladder inside Create to return proper object. Consumers of User need not recompile their code due to extension of Base.
Note that the function Create used to return different types of Base class objects at runtime. It acts like virtual constructor, also referred as Factory Method in pattern terminology.
Pattern world demonstrate different ways to implement the above concept. Also there are some potential design issues with the above code. Our objective is to provide some insights into virtual construction, creating objects dynamically based on some input. We have excellent books devoted to the subject, interested reader can refer them for more information.
— Venki. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Advanced C++ | Virtual Copy Constructor
- Calling virtual methods in constructor/destructor in C++
- What happens when a virtual function is called inside a non-virtual function in C++
- Difference between Virtual function and Pure virtual function in C++
- C | Advanced Pointer | Question 8
- Advanced C++ with boost library
- C | Advanced Pointer | Question 1
- C | Advanced Pointer | Question 2
- C | Advanced Pointer | Question 4
- C | Advanced Pointer | Question 7
- C | Advanced Pointer | Question 5
- C | Advanced Pointer | Question 10
- C | Advanced Pointer | Question 3
- Advanced C++ | Conversion Operators
- C | Advanced Pointer | Question 9