如何修复函数'func',以便它返回对象而不被破坏?
函数 'func' 必须将对象添加到列表中并返回它们,但会被销毁
Smoothy 抽象类有一个纯虚拟描述方法 ((。装饰器光滑 包含一个平滑,描述 (( 和 getPret (( 方法返回描述和价格 聚合光滑。 SmoothyCuFream 和 SmoothyCuUmbreluta 类添加了文本"cu crema" 分别在描述中所含的"Cu umbreluta"中含有。带有奶油的冰沙价格上涨2欧元,带雨伞的冰沙价格额外增加3欧元。 基本平滑类是没有奶油和没有雨伞的光滑,方法 说明 (( 返回 smothy 的名称
#include <iostream>
#include <vector>
using namespace std;
class Smoothy {
private:
int pret=0;
public:
virtual string descriere() = 0;
int getPret(){
return pret;
}
void setPret(int a) {
pret += a;
}
};
class BasicSmooty : public Smoothy {
private:
string nume;
public:
BasicSmooty(string n) :
nume { n } {}
string descriere() {
return nume;
}
};
class DecoratorSmoothy : public Smoothy {
private:
Smoothy* smooty;
public:
DecoratorSmoothy() = default;
DecoratorSmoothy(Smoothy* n) :
smooty{ n } {}
string descriere() {
return smooty->descriere();
}
int getPret() {
return smooty->getPret();
}
};
class SmootyCuFrisca : public DecoratorSmoothy {
private:
BasicSmooty bsc;
public:
SmootyCuFrisca(string desc) :
bsc{ desc } {}
string descriere() {
setPret(2);
return bsc.descriere() + " cu frisca ";
}
};
class SmootyCuUmbreluta : public DecoratorSmoothy{
private:
BasicSmooty bsc;
public:
SmootyCuUmbreluta(string desc) :
bsc{ desc } {}
string descriere() {
setPret(3);
return bsc.descriere() + " cu umbreluta ";
}
~SmootyCuUmbreluta() {
cout << "rip";
}
};
vector<Smoothy*> func(void)
{
std::vector<Smoothy*> l;
SmootyCuFrisca a1{ "smooty de kivi" };
SmootyCuUmbreluta a2{ "smooty de kivi" };
SmootyCuFrisca a3{ "smooty de capsuni" };
BasicSmooty a4{ "smooty simplu de kivi" };
l.push_back(&a1);
l.push_back(&a2);
l.push_back(&a3);
l.push_back(&a4);
return l;
}
int main() {
vector<Smoothy*> list;
// Here when i call func() objects are distroyed
list = func();
return 0;
}
在func
中,您将函数局部变量的地址存储在l
中。因此,当您从函数返回l
时,所有Smoothy*
现在都指向无效内存。
要解决此问题,您可以为添加到l
的每个指针分配内存,如下所示:
l.push_back(new Smoothy{a1}); // instead of l.push_back(&a1);
// etc. for a2, a3, ...
要真正摆脱这个问题,请考虑根本不使用指针。如果你的设计不需要它,你可以摆脱指针,你会省去很多麻烦。
好吧,当一个方法返回时,当然所有局部/自动变量都会被销毁。 在后期修订版 c++ 更改下,有 return && 修饰符,它调用 move 语义,这意味着对于您返回的 not const 本地/自动对象,它会窃取:克隆返回的对象,创建一个新对象并复制所有基元和对象指针,然后将对象指针设置为 null,以便析构函数无法删除/释放它们。 (请注意,没有空指针的 C 什么都不做! 当然,对于康斯特,它必须深度复制。