将多态性与引用一起使用。非const引用的初始化无效

时间:2016-08-08 19:54:34

标签: c++ reference polymorphism

我想在没有new运算符的情况下将多态性与引用一起使用。有一个BaseClass,其中有一些(在本例中为一个)虚拟方法。子类将实现它。

我创建了一个工厂函数,它创建了一个合适的实例。但是我得到了这个错误:

invalid initialization of non-const reference of type 'BaseClass&' from an rvalue of type 'SubOne'

代码是:

#include <iostream>

class BaseClass {
public:
    virtual void run() = 0;
};

class SubOne : public BaseClass {
public:
    virtual void run() override {
        std::cout << "I am SubOne!" << std::endl;
    }
};

class SubTwo : public BaseClass {
public:
    virtual void run() override {
        std::cout << "I am SubTwo!" << std::endl;
    }
};

BaseClass& baseFactory(int num) {

    switch(num) {

        case 1:
            return SubOne();

        case 2:
        default:
            return SubTwo();

    }

}

void executer(BaseClass& base) {

    // code...

    base.run();

    // code...

}

int main() {

    BaseClass& base = baseFactory( 1 );

    // code...

    executer(base);

    return 0;
}

2 个答案:

答案 0 :(得分:2)

您无法从返回引用的函数返回本地创建的对象:

BaseClass& baseFactory(int num) {
    ...
    return SubOne(); // Not allowed
}

这是因为一旦函数结束,本地对象就会超出范围,并且您最终会挂起引用。

您应该将函数更改为返回动态分配的对象,并将其存储到智能指针中:

BaseClass* baseFactory(int num) {
    ...
    return new SubOne();
}

unique_ptr<BaseClass> dyn { baseFactory(1) };

答案 1 :(得分:1)

如果您将baseFactory的返回类型更改为const,则会发现以下警告显示:(警告显示here

  

在函数'const BaseClass&amp; baseFactory(INT)':

     

27:27:警告:返回临时[-Wreturn-local-addr]

的引用      

31:27:警告:返回临时[-Wreturn-local-addr]

的引用

如您所见,您无法返回对临时变量的实际引用,因为正如警告所示,它 IS 是临时变量。您不能返回对不存在的内容的引用,也称为悬空引用。不幸的是,唯一的方法是使用指针,又名:

BaseClass* baseFactory(int num) {

    switch(num) {

        case 1:
            return new SubOne();

        case 2:
        default:
            return new SubTwo();

    }

}

这个问题是调用函数(这里是main)必须处理清理,否则会出现内存泄漏。或者,就像@dasblinkenlight已经包含在他的答案中一样,你可以使用 RAII R esource A cquisition s I nitialization),并将该类保存在智能指针中,智能指针的析构函数将删除该对象。