简体   繁体   中英

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

#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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM