Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling different base class constructors depending on input parameter value

I have the following scenario:

Depending on the input value to a Derived class's constructor I need to call a different Base class constructor.

Such as:

struct Base
{
    Base() : v(0) {}
    Base(int _v) : v(_v) {}

    int v;
};

struct Derived
{
    Derived(int v) /* if v == 42 call Base() else call Base(int) */ {}
};

int main()
{
    Derived f2(42);
    Derived f1(1);
}

With my current knowledge of C++ I think this is not possible, so I ask the community if they are aware of any hacks, or dirty code that will make this feasible. Please don't let the simple ints misguide you, the real life scenario is much more complex. Feel free to mix in C++11 magic.

Edit: Also, I don't want to use an "init" function which depending on the value of the parameter initializes differently the things.

like image 728
Ferenc Deak Avatar asked Apr 29 '15 07:04

Ferenc Deak


People also ask

How do you call a base class parameterized constructor?

To call the parameterized constructor of base class inside the parameterized constructor of sub class, we have to mention it explicitly. The parameterized constructor of base class cannot be called in default constructor of sub class, it should be called in the parameterized constructor of sub class.

Can we pass parameter to base class constructor?

In this example, the constructor for the base class is called before the block for the constructor is executed. The base keyword can be used with or without parameters. Any parameters to the constructor can be used as parameters to base , or as part of an expression.

How can you pass parameters to the constructors of base classes in multiple inheritance?

To pass arguments to a constructor in a base class, use an expanded form of the derived class' constructor declaration, which passes arguments along to one or more base class constructors. Here, base1 through baseN are the names of the base classes inherited by the derived class.

What happens when a base class constructor is made parameterized?

If a class do not have any constructor then default constructor will be called. But if we have created any parameterized constructor then we have to initialize base class constructor from derived class. We have to call constructor from another constructor. It is also known as constructor chaining.


1 Answers

This is indeed a quite a strange request, maybe you should reconsider the general approach. What is the meaning of this particular 42 value? What is the question for which 42 is the answer? Maybe you should have two sibling Deriveds, or subclass Derived for x==42 case or for x!=42 case, etc. Or maybe 42 comes from a different-type object and you can use a separate constructor for that type?

But if you indeed want to accomplish what you have asked, one possible approach is to have two somehow different constructors in Derived and a "named constructor" (static function) to route between them. Something like (did not check for compilability, but the idea should be clear):

struct Derived {
private:
    Derived(int x): Base(x) {} 
    Derived(): Base() {}
public:
    static Derived ConstructDerived(int x) {
        if (x==42) return Derived();
        else return Derived(x);
    }
};

// usage
Derived a = Derived::ConstructDerived(42);
Derived b = Derived::ConstructDerived(43);

For this you will also need copy constructor, but you can also return pointers etc.

Another approach, if the value of 42 is fixed at compile time, is to use templates and specialize the constructor or even the class for a particular value of 42.

Another approach that I think should work, require base class to be copy- or move-constructible:

struct Derived {
    Derived(int x): Base( (x == 42)? Base() : Base(x) ) {}
}; 
like image 118
Petr Avatar answered Sep 22 '22 05:09

Petr