Home > other >  How to create reference to an objcect and initialize it as a child class with conditinal operator?
How to create reference to an objcect and initialize it as a child class with conditinal operator?

Time:01-18

#include<iostream>

class A {
public:
    virtual bool isB() = 0;
};

class B : public A{
public:
    B() { }
    bool isB() {std::cout << " not B\n"; return true;}
};

class C : public A {
public:
    C() { }
    bool isB() {std::cout << " not B\n"; return false;}
};
int main() {
    B b;
    A& a = (b.isB()) ? a(B()) : a(C()); // here is the problem
}

I also tried to make it as static cast to pointer of child class but it seems to not work as well. In real code myfunction takes A reference as a parameter and the condition depends on other part of code.

CodePudding user response:

If I understand your question correctly, you want to create either a B or a C instance, depending on a.isB(), where a is a given reference to A. a can reference either a B or a C instance.

Creating an instance of B or C based on a is easy:

if (a.isB()) {
    B b;
} else {
    C c;
}

The above code is not very useful. You want to have a valid A& referencing the instance you just created. In C you cannot create a A& and instantiate a derived object at the same time. Reference must always reference something that exists. So your code cannot work. Also, any reference to A that references either b or c existing after the if-statement will be a dangling reference: Once you exit the scope of either branch the instance gets destructed.

As a consequence, you would have to work with pointers, ideally smart pointers. You could write a function

std::unique_ptr<A> create(bool createB){
    if (createB) {
        return std::make_unique<B>();
    }
    else {
        return std::make_unique<C>();
    }
}

that returns an std::unique_ptr<A> from a B or C instance, depending on the input variable createB.

In your code, you could call it like this:

B b;
auto x = create(b.isB());
A& xref = *x;

Keep in mind, that the variable x must outlive xref. Otherwise xref is a dangling reference and using it is undefined behavior.

Note that the function accepts a bool, not A const&. I personally prefer this style, because the signature std::unique_ptr<A> create(A const& a) does not properly convey the intent. I would be confused by this. If you have more than two derived classes, you could have create accept an enum, where each value corresponds to a derived class.

Here is the full code: https://godbolt.org/z/EEqPMvhdE

  • Related