【问题标题】:Using a static pointer to a class memory mangement?使用指向类内存管理的静态指针?
【发布时间】:2011-12-12 08:06:12
【问题描述】:

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

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++ 技术”的新手,我担心这行不通。我需要定义一个复制构造函数吗?向量会弄乱我的引用计数吗?我也愿意接受有关更好方法的建议。我想我可以将纹理保留在类之外并在初始化每颗星时传递一个引用,但我更喜欢将纹理留在类中......

【问题讨论】:

  • 为什么要添加 refcount 的编译。为什么不 sf::Texture Star::starTexture;让堆栈解决压力?

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


【解决方案1】:

是的,如果你没有为你的班级明确定义copy constructorcopy assignment operator,它会搞砸的。

vector 这样的STL 容器具有copy-by-value 语义。当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. 当你的对象被删除时,非静态成员对象的析构函数被调用

在这种情况下,智能指针的复制函数将正确地增加引用计数,而 它的析构函数将减少引用计数,如果引用计数等于0,则释放资源。

【讨论】:

  • 谢谢!不过,我对 std::tr1::shared_ptr 有点困惑,Class star 的每个实例是否都可以访问相同的纹理,还是每个新星都会创建一个新纹理?我可以在标题中声明一个静态 shared_ptr 吗?
  • 这取决于。当您创建一个新的星形对象时,它会在其构造函数中创建一个新纹理。因此,如果您创建 10 个起始对象(在堆栈上或在堆上),它们内部有 10 种不同的纹理。但是,当您复制星形对象时,例如,复制到矢量或另一个星形对象时,这些对象共享相同的纹理。不要对 shared_ptr 使用静态。
  • 您可能需要弄清楚智能指针通常是如何工作的。它很强大。只需谷歌它。)
  • 再次感谢,我会调查一下。
猜你喜欢
  • 2015-05-19
  • 2015-10-20
  • 2019-03-14
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多