使用指向类内存管理的静态指针?

rep*_*ant 2 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

    starVector.push_back(star);
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*c Z 5

是的,如果你没有明确定义copy constructorcopy assignment operator为你上课,它会搞砸.

STL容器vector具有按值复制的语义.将Star对象复制到a时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())
{
  ...  
}
Run Code Online (Sandbox Code Playgroud)

这保证可以通过语言功能工作:

  1. 复制对象时,将调用非静态成员对象的复制功能.
  2. 删除对象时,将调用非静态成员对象的析构函数.

在这种情况下,复制智能指针的功能将正确地增加引用计数,而它的析构函数将减少引用计数,并在ref count等于0时释放资源.