使用静态指针来进行类内存管理?

时间:2011-10-21 06:15:15

标签: c++ memory static vector copy-constructor

我在游戏中有一个明星课,我希望他们使用相同的纹理,所以我想出了这个代码...

sf::Texture* Star::starTexture = NULL;
unsigned int Star::refCount = 0;

Star::Star() : starSpeed(0), starScale(0), locX(0), locY(0)
{
    if (starTexture == NULL)
    {
        starTexture = new sf::Texture();
    }

    refCount++;
}

Star::~Star()
{
    refCount--;

    if (refCount == 0)
    {
        delete starTexture;
        starTexture = NULL;
    }
}

我正在使用这样的星级......

for (int i = 0; i < STAR_COUNT; ++i)
{
    Star star;

    star.Initialize(/* blah blah */);

    starVector.push_back(star);
}

我是“高级c ++技术”的新手,我担心这不起作用。我需要定义一个复制构造函数吗?矢量会使我的引用计数搞乱吗?我愿意接受更好的方法来做到这一点。我想我可以将纹理保留在类之外并在初始化每个星时传递引用,但是我将纹理保留在类中...

1 个答案:

答案 0 :(得分:5)

是的,如果你没有为你的班级明确定义copy constructorcopy assignment operator,那就太麻烦了。

vector之类的STL容器具有按值复制语义。将Star对象复制到vector时,会复制其中的原始指针。所以你现在有多个指向单个内存的指针,这肯定会使你快速走向未定义的行为,充其量。

您应该做的是明确定义这些功能。手动执行该内存的深层复制并正确增加引用计数。

更好的方法是在类中保存像boost::shared_ptrstd::tr1::shared_ptr这样的RAII对象,让它自动为您处理资源管理(包括重新计算内容)。那么你就不需要再明确定义那些函数了。

class Star
{
..
private:
  std::tr1::shared_ptr<sf::Texture> m_starTexture;
};

// link the smart pointer w/ resource
Star::Star(): m_starTexture(new Texture())
{
  ...  
}

这保证可以通过语言功能实现:

  1. 复制对象时,称为非静态成员对象的复制功能
  2. 删除对象后,将调用非静态成员对象的析构函数
  3. 在这种情况下,复制智能指针的功能将正确增加引用计数 它的析构函数将减少引用计数,如果引用计数等于0,则释放资源。