Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to switch to a different base class constructor at runtime?

Suppose I'm writing Derived and have to inherit from Base, which I don't control and has two separate constructors and a deleted copy and move constructors:

struct Base {
    Base(int i);
    Base(const char *sz);
    Base(const Base&) = delete;
    Base(const Base&&) = delete;
};

struct Derived {
    Derived(bool init_with_string);
};

Now, depending on the value of another_param I have to initialize my base class using either a constructor or the other; if C++ was a bit less strict it would be something like:

Derived::Derived(bool init_with_string) {
    if(init_with_string) {
        Base::Base("forty-two");
    } else {
        Base::Base(42);
    }
}

(this would also be useful for all the cases where it's cumbersome to calculate values to pass to base class constructors/fields initializers in straight expressions, but I'm digressing)

Unfortunately, even if I don't see particular codegen or object-model obstacles to this kind of thing, this isn't valid C++, and I cannot think of easy workaround.

Is there some way around this that I'm not aware of?

like image 357
Matteo Italia Avatar asked Apr 28 '17 13:04

Matteo Italia


People also ask

Can we override base class constructor?

It does not have a return type and its name is same as the class name. But, a constructor cannot be overridden.

Does base class constructor get called automatically?

Whenever the derived class's default constructor is called, the base class's default constructor is called automatically. To call the parameterized constructor of base class inside the parameterized constructor of sub class, we have to mention it explicitly.

Why base class constructors are executed first and then derived?

Because m_id lives in the Base portion of the object, the Base constructor is the only constructor that can initialize that value. Note that it doesn't matter where in the Derived constructor member initializer list the Base constructor is called -- it will always execute first.

Is it possible to inherit constructors of its base class in C++?

Constructor is automatically called when the object is created. Multiple Inheritance: Multiple Inheritance is a feature of C++ where a class can derive from several(two or more) base classes. The constructors of inherited classes are called in the same order in which they are inherited.


1 Answers

A static function will work fine here

struct Base {
    Base(int i);
    Base(const char *sz);
    Base(const Base&) = delete;
    Base(const Base&&) = delete;
};

struct Derived : Base {
   using Base::Base;

   static Derived construct(bool with_string) {
      if(with_string) return { "forty-two" };
      return { 42 };
   }
};

Notice that this does not require a move, nor a copy constructor. If you want to have this as a local, you need to bind it to a reference in order to avoid moving it

auto &&w = Derived::construct(true);
auto &&wo = Derived::construct(false);
like image 157
Johannes Schaub - litb Avatar answered Sep 18 '22 17:09

Johannes Schaub - litb