8
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();

仍然是一个错误,因为三元运算符期望可转换类型。

处理这个问题的最佳解决方案是什么?

4

4 回答 4

6

您不能?:在这种情况下使用 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)();  
于 2013-08-15T12:21:43.417 回答
1

您可以修改您的代码如下

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

但请确保稍后删除 obj1

于 2013-08-15T12:24:09.610 回答
1

如果您想要引用,则不能将临时绑定到它,除非它是const Base &. 这意味着您需要一个实际的对象来绑定,所以让我们从它开始:

Derived1 d1;
Derived2 d2;

但是,您可以使用函数(包括 lambda)获取非常量引用。如果 lambdas 不可用,则普通函数需要将d1d2作为参数。

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

现在创建obj很容易:

Base &obj = choose(condition);
于 2013-08-15T12:25:43.607 回答
0

这会起作用:

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

然后在你的代码末尾你必须添加一个

delete obj
于 2013-08-15T12:23:19.347 回答