C ++基类引用使用不同的派生类对象进行初始化

时间:2013-08-15 12:14:26

标签: c++ reference constructor

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 个答案:

答案 0 :(得分:5)

在这种情况下,您无法使用?:,因为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)();  

答案 1 :(得分:1)

您可以修改以下代码

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

但请确保稍后删除obj1

答案 2 :(得分:1)

如果您想要引用,除非是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);

答案 3 :(得分:0)

这样可行:

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

然后在代码的末尾添加

delete obj