我想在没有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;
}
答案 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),并将该类保存在智能指针中,智能指针的析构函数将删除该对象。