我有一个带有静态工厂构造函数的类,它返回指向所创建对象的指针。
我必须将该对象声明为命名空间内的静态对象,但我不知道如何正确删除它
class Foo
{
public:
Foo(int, int* );
virtual ~Foo();
static Foo* MyFooInitializer(int n )
{
int *p = new int[n];
for (int i=0; i<n; i++)
p[i]=i;
Foo *ret = new Foo(n,p);
delete p;
return ret;
}
int someFooFunction(int a);
}
然后在我的命名空间中我有一个static inline
函数
namespace MyNamespace
{
static inline void myfunction()
{
static Foo *foo1 = Foo::MyFooInitializer(10);
int y = somevalue();
int x = foo1->someFooFunction(int y);
}
}
我这里显然有内存泄漏,因为该对象从未被删除。
重要的事实是我需要将 foo1 声明为静态的,因为一旦创建,它在所有程序中必须是相同的对象并且必须是唯一的(它跟踪一些变量)。
可能这是一个设计问题,但我不知道如何在我的程序退出时删除它,或者当我明确要删除它以重新初始化它时。
解决方案:
我这样修改了 MyFooInitializer
的主体:
static Foo* MyFooInitializer(int n )
{
int *p = new int[n];
for (int i=0; i<n; i++)
p[i]=i;
static Foo ret = Foo(n,p);
delete[] p;
return &ret;
}
这允许我在程序终止时正确释放所有内存。 Valgrind 说所有的堆内存都被释放了!
最佳答案
这里不需要在堆上分配 Foo:
static Foo* MyFooInitializer(int x) {
static Foo some_foo(x);
return &some_foo;
}
该代码中没有泄漏,当您的程序结束时 Foo 将被销毁。
请注意,如果 MyFooInitializer
返回的指针实际上指向某个继承自 Foo
的类,那么您只需为静态变量使用派生类型:
static Foo* MyFooInitializer(int x) {
static SomeFooDerived some_foo(x);
return &some_foo;
}
编辑:由于您提供了实际的函数体,所以我的回答是有效的。你会这样做:
static Foo* MyFooInitializer(int n ) {
// Don't know what this p is, anyway...
int *p = new int[n];
for (int i=0; i<n; i++)
p[i]=i;
static Foo ret(n,g); // what is g?
delete[] p; // smart pointer plx
return &ret;
}
关于c++ - 静态工厂方法和静态对象内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11137874/