希望我的头衔不会太混乱。我正在尝试使用SFML为我的游戏编写声音管理器。我正在尝试用“智能指针”std :: shared_ptr替换我的新/删除。这是我到目前为止所做的。
/* SoundManager.h */
#ifndef SOUNDMANAGER_H
#define SOUNDMANAGER_H
#include <SFML/Audio.hpp>
#include <string>
#include <memory>
class SoundManager
{
public:
~SoundManager();
struct jteSound
{
sf::Sound snd;
sf::SoundBuffer sndBuffer;
std::string name;
};
//Load a new sound from path and store it in audio bank bnk.
//Banks are simply std::vectors of type jteSound.
void registerNewSound(std::vector<std::shared_ptr<jteSound>> &bnk, std::string path, std::string sndName);
//Footsteps bank
std::vector<std::shared_ptr<jteSound>> bnkFootsteps;
};
#endif // SOUNDMANAGER_H
/* SoundManager.cpp */
#include "SoundManager.h"
#include <stdlib.h>
SoundManager::~SoundManager()
{
/*
//Cleanup each sound bank that we use.
for (std::vector<jteSound*>::iterator it = bnkFootsteps.begin(); it != bnkFootsteps.end(); ++it) {
delete *it;
}
*/
}
void SoundManager::registerNewSound(std::vector<std::shared_ptr<jteSound>> &bnk, std::string path, std::string sndName)
{
static int counter = 0;
for (int i = counter; counter <i+1; counter++) {
bnk.push_back(jteSound);
bnk[i]->name = sndName;
bnk[i]->sndBuffer.loadFromFile(path);
bnk[i]->snd.setBuffer(bnk[i]->sndBuffer);
}
}
bnk.push_back(jteSound);
给了我编译错误。如果我删除该行,程序将编译,但崩溃。我尝试了emplace_back()
或jteSound*
或new jteSound
之类的内容,但没有任何效果。我总是得到一个冗长的编译器错误或立即运行时崩溃。当我使用常规指针和new / delete时,请参阅https://bpaste.net/show/fa684f2f2d5e和https://bpaste.net/show/c74ac701ce7a,代码按预期工作。任何想法都赞赏!
答案 0 :(得分:1)
std::vector
中的元素类型为std::shared_ptr<jteSound>
,这意味着std::vector::push_back
只会接受该类型的实例。
要使代码正常工作,您有两种选择。第一种是使用std::make_shared
辅助函数,如下所示:
bnk.push_back(std::make_shared<jteSound>());
// the equivalent counterpart is:
bnk.push_back(std::shared_ptr<jteSound>(new jteSound));
第二种是使用std::vector::emplace
,如下所示:
bnk.emplace(bnk.end(), new jteSound);
正如下面的评论警告的那样,使用第二个选项是冒险的,因为当new jteSound
成功但std::vector::emplace
必须重新分配内存并失败时,它可能导致内存泄漏。