A reference to a C ++ base class is initialized with another derived class object

class Base { public: void operator()() { func(); } private: virtual void func() {} }; class Derived1 : public Base { private: void func() override {/*do something*/} }; class Derived2 : public Base { private: void func() override {/*do something else*/} }; 

Because I want to use operator overloading,
Link is a better option than a pointer.

What I intend to do is:

 if (condition) { Base& obj = Derived1(); } else { Base& obj = Derived2(); } 

But obj will be destroyed and completed.

 Base& obj; if (condition) { obj = Derived1(); } else { obj = Derived2(); } 

Will not work,
Because the link must be initialized when declared.

If I try:

 Base& obj = condition ? Derived1() : Derived2(); 

Another mistake, since the ternary operator expects a convertible type.

What is the best solution to solve this problem?

+6
source share
4 answers

You cannot use ?: In this case, since Derived1 and Derived2 are different types .

One possible way is to use a pointer, this is valid:

 condition ? pObj.reset(new Derived1()) : pObj.reset(new Derived2()); 

or

 #include <memory> std::unique_ptr<Base> pObj; if (condition) { pObj.reset(new Derived1()); } else { pObj.reset(new Derived2()); } 

You can call operator() as follows:

 (*pObj)(); 
+4
source

You can change your code below

 Base *obj1; if (condition) { obj1 = new Derived1(); } else { obj1 = new Derived2(); } Base &obj = *obj1; 

But make sure you uninstall obj1 later

+1
source

If you want a link, you cannot bind a temporary link to it unless it is const Base & . This means that you need the actual object to bind, so let's start with this:

 Derived1 d1; Derived2 d2; 

However, you can get a non-constant link with a function (including lambda). If lambda is not available, the normal function should take the values d1 and d2 as parameters.

 auto choose = [&](bool b) -> Base & { if (b) {return d1;} else {return d2;} }; 

Now creating obj easy:

 Base &obj = choose(condition); 
+1
source

This will work:

 Base* obj; if (condition) { obj = new Derived1; } else { obj = new Derived2; } 

and then at the end of your code you should add

 delete obj 
0
source

Source: https://habr.com/ru/post/951801/


All Articles