0

我有一个带有静态工厂构造函数的类,它返回一个指向所创建对象的指针。

我必须将对象声明为命名空间内的静态对象,但我不知道如何正确删除它

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 说所有的堆内存都被释放了!

4

3 回答 3

4

这里不需要在堆上分配 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;
}
于 2012-06-21T12:15:36.743 回答
0

如果您绝对需要动态创建 foo1,则编写一个额外的类并按值使其静态/全局。然后使用它的析构函数来删除对象。

class MasterControlClass
{
    public:
    Foo* foo1;
    MasterControl(){foo1 = NULL;}
    ~MasterControl(){delete(foo1), foo1 = NULL;}
};



static inline void myfunction()
{
     static MasterControlClass mcp;
     mcp.foo1 = Foo::MyFooInitializer(10); 
}

这样,当您的程序关闭时,mcp 析构函数将被调用并进行清理。如果要重新初始化,则必须在每次分配时删除 foo1 ,只需添加

if(mcp.foo1)
{
    delete mcp.foo1;
    mcp.foo1= NULL;
}

或者更好的是,将其移至 mcp 的方法中。

于 2012-06-21T12:37:43.470 回答
0

怎么样

static inline void  myfunction()
{
    static std::unique_ptr<Foo> foo1(Foo::MyFooInitializer(10));
    int y = somevalue();
    int x = foo1->someFooFunction(int y);
} 
于 2012-06-21T12:16:25.893 回答