我在游戏中有一个明星课,我希望他们使用相同的纹理,所以我想出了这个代码...
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 ++技术”的新手,我担心这不起作用。我需要定义一个复制构造函数吗?矢量会使我的引用计数搞乱吗?我愿意接受更好的方法来做到这一点。我想我可以将纹理保留在类之外并在初始化每个星时传递引用,但是我将纹理保留在类中...
答案 0 :(得分:5)
是的,如果你没有为你的班级明确定义copy constructor
和copy assignment operator
,那就太麻烦了。
vector
之类的STL容器具有按值复制语义。将Star
对象复制到vector
时,会复制其中的原始指针。所以你现在有多个指向单个内存的指针,这肯定会使你快速走向未定义的行为,充其量。
您应该做的是明确定义这些功能。手动执行该内存的深层复制并正确增加引用计数。
更好的方法是在类中保存像boost::shared_ptr
或std::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())
{
...
}
这保证可以通过语言功能实现:
在这种情况下,复制智能指针的功能将正确增加引用计数 它的析构函数将减少引用计数,如果引用计数等于0,则释放资源。