簡體   English   中英

C ++基類引用使用不同的派生類對象進行初始化

[英]C++ base class reference initialize with different 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*/}
};

因為我想使用運算符重載,
引用是比指針更好的選擇。

我打算做的是:

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

但是obj將被銷毀並且范圍結束。

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

也不會工作,
因為引用需要在聲明時初始化。

如果我嘗試:

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

還是一個錯誤,因為三元運算符期望可轉換類型。

處理這個問題的最佳解決方案是什么?

您不能使用?:在這種情況下,Derived1和Derived2是不同的類型

一種可能的方法是使用指針,這是有效的:

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

要么

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

你可以這樣調用operator()

(*pObj)();  

您可以修改代碼,如下所示

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

但請確保稍后刪除obj1

如果你想要引用,你不能綁定一個臨時的,除非它是一個const Base & 這意味着你需要一個實際的對象來綁定,所以讓我們從那開始:

Derived1 d1;
Derived2 d2;

但是,您可以使用函數(包括lambda)獲取非const引用。 如果lambdas不可用,則正常函數需要將d1d2作為參數。

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

現在創建obj很簡單:

Base &obj = choose(condition);

這可行:

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

然后在代碼的末尾你必須添加一個

delete obj

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM