bib*_*tha 34 c++ memory-management factory
从类中返回对象时,何时是释放内存的正确时间?
例,
class AnimalLister
{
public:
Animal* getNewAnimal()
{
Animal* animal1 = new Animal();
return animal1;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我创建一个Animal Lister的实例并从中获取Animal引用,那么我应该在哪里删除它?
int main() {
AnimalLister al;
Animal *a1, *a2;
a1 = al.getNewAnimal();
a2 = al.getNewAnimal();
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是AnimalLister没有办法跟踪动物创建的列表,所以我如何更改这些代码的逻辑以便有办法删除创建的对象.
Ecl*_*pse 36
根据您的使用情况,您可以在此处使用以下几种选项:
每次创建动物时制作副本:
class AnimalLister
{
public:
Animal getNewAnimal()
{
return Animal();
}
};
int main() {
AnimalLister al;
Animal a1 = al.getNewAnimal();
Animal a2 = al.getNewAnimal();
}
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
返回一个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();
}
Run Code Online (Sandbox Code Playgroud)
优点:
Animal
定义复制构造函数.缺点:
跟踪所有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.
Run Code Online (Sandbox Code Playgroud)
优点:
Animal
有限时间内需要一堆s的情况,并计划一次性释放它们.Animal
放在一个内存中delete
.Animal
定义复制构造函数.缺点:
Chr*_*ung 24
我建议返回一个std::tr1::shared_ptr
(或者boost::shared_ptr
,如果你的C++实现没有TR1)而不是原始指针.所以,而不是使用Animal*
,std::tr1::shared_ptr<Animal>
而是使用.
共享指针为您处理引用跟踪,如果没有任何引用,则自动删除该对象.
最简单的方法是返回智能指针而不是常规指针.例如:
std::auto_ptr< Animal> getNewAnimal()
{
std::auto_ptr< Animal > animal1( new Animal() );
return animal1;
}
Run Code Online (Sandbox Code Playgroud)
如果您能够使用TR1或Boost,您还可以使用shared_ptr <>.
指针和分配内存的经典问题.这是责任 - 谁负责清理AnimalLister对象分配的内存.
您可以在AnimalLister中存储指向每个已分配动物的指针,并让它清理干净.
但是,你确实有几个指向动物坐在main()中的指针,这些指针将引用被删除的内存.
我认为引用计数解决方案比滚动自己的解决方案更有效的原因之一.
实现'freeAnimal(Animal*)'方法,显然需要删除动物指针.
另一种方法是直接返回动物对象,没有指针,没有新的调用.复制构造函数将确保调用者获取他们可以存储在堆或堆栈上的动物对象,或者根据需要复制到容器中.
所以:
class AnimalLister
{
Animal getAnimal() { Animal a; return a; }; // uses fast Return Value Optimisation
};
Animal myownanimal = AnimalLister.getAnimal(); // copy ctors into your Animal object
Run Code Online (Sandbox Code Playgroud)
RVO意味着返回对象而不是指针实际上更快(因为编译器不创建新对象并将其复制到调用者的对象中,而是直接使用调用者的对象).
归档时间: |
|
查看次数: |
23188 次 |
最近记录: |