从类返回对象时,什么时候释放内存合适?
例子,
class AnimalLister
{
public:
Animal* getNewAnimal()
{
Animal* animal1 = new Animal();
return animal1;
}
}
如果我创建一个 Animal Lister 实例并从中获取 Animal 引用,那么我应该在哪里删除它?
int main() {
AnimalLister al;
Animal *a1, *a2;
a1 = al.getNewAnimal();
a2 = al.getNewAnimal();
}
这里的问题是 AnimalLister 没有办法跟踪创建的动物列表,所以我如何更改此类代码的逻辑以删除创建的对象。
最佳答案
根据您的使用情况,您可以在此处使用几个选项:
每次创建动物时都复制一份:
class AnimalLister { public: Animal getNewAnimal() { return Animal(); } }; int main() { AnimalLister al; Animal a1 = al.getNewAnimal(); Animal a2 = al.getNewAnimal(); }
优点:
- 简单易懂。
- 不需要额外的库或支持代码。
缺点:
- 需要
Animal
拥有一个表现良好的复制构造函数。 - 如果
Animal
可能涉及大量复制庞大而复杂,尽管 return value optimization在许多情况下可以缓解这种情况。 - 如果您计划返回派生自
Animal
的子类,则此方法无效因为他们将是sliced平淡无奇Animal
,丢失子类中的所有额外数据。
返回
shared_ptr<Animal>
:class AnimalLister { public: shared_ptr<Animal> getNewAnimal() { return new Animal(); } }; int main() { AnimalLister al; shared_ptr<Animal> a1 = al.getNewAnimal(); shared_ptr<Animal> a2 = al.getNewAnimal(); }
优点:
- 适用于对象层次结构(无对象切片)。
- 无需复制大型对象。
- 无需
Animal
定义一个复制构造函数。
缺点:
- 需要 Boost 或 TR1 库,或其他智能指针实现。
跟踪所有
Animal
AnimalLister
中的分配class AnimalLister { vector<Animal *> Animals; public: Animal *getNewAnimal() { Animals.push_back(NULL); Animals.back() = new Animal(); return Animals.back(); } ~AnimalLister() { for(vector<Animal *>::iterator iAnimal = Animals.begin(); iAnimal != Animals.end(); ++iAnimal) delete *iAnimal; } }; int main() { AnimalLister al; Animal *a1 = al.getNewAnimal(); Animal *a2 = al.getNewAnimal(); } // All the animals get deleted when al goes out of scope.
优点:
- 非常适合需要大量
Animal
的情况s 在有限的时间内,并计划一次释放它们。 - 轻松适应自定义内存池并释放所有
Animal
s 在一个delete
. - 适用于对象层次结构(无对象切片)。
- 无需复制大型对象。
- 无需
Animal
定义一个复制构造函数。 - 无需外部库。
缺点:
- 上面写的实现不是线程安全的
- 需要额外的支持代码
- 不如前两种方案清晰
- 不明显的是,当 AnimalLister 超出范围时,它会带走 Animals。与 AnimalLister 相比,您不能再继续使用 Animals。
- 非常适合需要大量
关于c++ - 在 C++ 中返回对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/204396/