C ++:破坏静态东西的最佳方法

时间:2010-08-28 07:13:32

标签: c++ static destructor

当我有一个包含静态内容的类时,如何在应用程序结束时以最佳方式释放内存?

foo.h中

class GLUtesselator;

class Foo
{
private:
    static GLUtesselator *tess;
public:
    Foo();
    virtual ~Foo();
}

Foo.cpp中

#include "Foo.h"

#include <GL/glu.h>

GLUtesselator *Foo::tess = gluNewTess(); // System call

Foo::Foo() {}
Foo::~Foo()
{
     // And of course I don't want to destruct it here,
     // because I'm going to use the tesselator in other instances of Foo
     // Otherwise:
     // gluDeleteTess(tess);
}

是否有更好的替代方法来制作删除静态内容的方法并在应用终止时调用它? 或者我可以说:“哦,无论如何,应用程序终止。操作系统将释放内存......”?

由于

4 个答案:

答案 0 :(得分:7)

简单。不要将静态成员作为指针 然后它将被正确地构造和破坏。

foo.h中

#include <GL/glu.h>

class Foo
{
    private:
        static GLUtesselator  tess;
    public:
                 Foo();
        virtual ~Foo();
};

Foo.cpp中

// 
GLUtesselator  Foo::tess;

如果你必须使用gluNewTess()和gluDeleteTess(),那么你可以使用共享指针。我没有编译器,所以确切的用法可能不是绝对正确的。但是shared_ptr确实具备这种能力。

foo.h中

#include <GL/glu.h>

typedef std::shared_ptr<GLUtesselator,void (*)(GLUtesselator*)> AutoGluTess;
class Foo
{
    private:
        static AutoGluTess  tess;
    public:
                 Foo();
        virtual ~Foo();
};

Foo.cpp中

// 
AutoGluTess    Foo::tess(gluNewTess(), &gluDeleteTess);

答案 1 :(得分:2)

你不需要销毁它。我知道的所有操作系统都会正确释放内存并释放对象在应用程序终止时保留的任何资源(注意:析构函数不会自动调用,但资源将被释放)。

如果确实想破坏它,

  1. 不要像Martin York描述的那样使用指针,
  2. 或者(如果你需要一个指针),使用auto_ptrtr1::unique_ptr,以便当指针对象超出范围时(在应用程序结束时为静态变量)自动删除它)。

答案 2 :(得分:2)

表示全局静态变量:

CFoo* pFoo= NULL;

void DoneFoo()
{
    delete pFoo;
}

void Init()
{
    pFoo= new CFoo();
    atexit(DoneFoo);
}

或:

class CFoo
{
     ......
};

#define NewFoo(F_name)                                                             \
    CFoo* F_name##Init();                                                          \
    void  F_name##Done();                                                          \
    CFoo* F_name= F_name##Init();                                                  \
    CFoo* F_name##Init()  { CFoo* F= new CFoo(); atexit(F_name##Done); return F; } \
    void  F_name##Done()  { delete F_name; }    

NewFoo(F1);
成员静态变量的

class CFoo
{
    static int* pKuku;
    static void DoneKuku() { delete pKuku;                     }
    static int* InitKuku() { atexit(DoneKuku); return new int; }
public:
};

int* CFoo::pKuku= CFoo::InitKuku();

我认为让操作系统自动释放内存并不是一个好主意,因为你会有内存泄漏。当你有“合法的”内存泄漏时 - 更难注意到“非法”内存泄漏,所以你应该努力完全没有内存泄漏。

答案 3 :(得分:1)

因为它是静态的,所以只会有一个实例。除非这个GLUtesselator非常庞大,否则我怀疑你自己是否需要自由释放它。

像你说的那样,“哦,无论如何,应用程序终止。操作系统将释放内存......”