[英]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不可用,則正常函數需要將d1
和d2
作為參數。
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.