В моем коде у меня есть класс SoundManager, который содержит и работает со всеми звуками для моей игры. Этот класс должен быть создан, и его методы называются несколькими другими классами. Однако я желаю только одного набора звуков, занимающих память, поэтому в интересах эффективности все активы объявляются как static shared_ptrs.Удаление объектов, на которые указывают интеллектуальные указатели
#include "SoundManager.h"
static shared_ptr<ISoundEngine> sEngine;
static shared_ptr<ISoundSource> hoverSound;
static shared_ptr<ISoundSource> confirmSound;
static shared_ptr<ISoundSource> mainBGM;
static shared_ptr<ISound> bgmInterface;
SoundManager::SoundManager(void)
{
//first we need to create the irrKlang sound engine instance
if(!sEngine)
{
sEngine.reset(createIrrKlangDevice());
}
if(!hoverSound)hoverSound.reset(sEngine->addSoundSourceFromFile("Sounds/ButtonHover.mp3"));
if(!confirmSound)confirmSound.reset(sEngine->addSoundSourceFromFile("Sounds/ButtonConfirm.mp3"));
if(!mainBGM)mainBGM.reset(sEngine->addSoundSourceFromFile("Sounds/mainBGM.mp3"));
//set some default volumes
hoverSound->setDefaultVolume(1.0f);
confirmSound->setDefaultVolume(0.4f);
mainBGM->setDefaultVolume(0.5f);
}
SoundManager::~SoundManager(void)
{
}
Это Soundmanager конкретизируется в моей основной функции() и каждый раз, когда мне нужно загрузить titlescreen (Soundmanager конкретизируется в этом titlescreen классе тоже). Инициализация и уничтожение экрана заголовка снова и снова не вызывают проблем. Статические объекты shared_ptrs не уничтожаются, поскольку они все еще используются экземпляром основных функций SoundManager.
Теперь все это работает на практике для запуска моей игры. Однако когда дело доходит до выхода из строя, когда статические объекты выше демонтируются, на меня бросаются необработанные исключения времени выполнения (нарушения доступа). С отладчиком VS2012, указывающим на строку в памяти.h.
private:
virtual void _Destroy()
{ // destroy managed resource
delete _Ptr; <<<<<<<<<The debugger points to this line
}
Я должен был понять, что похож на Obj-C, C++ shared_ptrs использовать эталонные счетчики, чтобы гарантировать, что объекты не удаляются, пока объект не существует, что требует их использования больше. Я не понимаю, что может вызвать эти ошибки.
Возможно, важная часть, которую я не должен опускать: моя игра завершена вызовом для выхода (0); как можно ближе к функции main(). Я не предпринимал никаких действий для очистки членов SoundManager до этого, поскольку я думал, что shared_ptr обработал это.
Кто-нибудь знает, что может вызвать проблемы с моей очисткой?
какого типа shared_ptr это они? Вызов 'reset()' на 'std :: shared_ptr' или' boost :: shared_ptr' очистит это 'shared_ptr', если он последний, ссылающийся на объект, тогда объект будет удален, если объект еще не был общий. – mark
Вы уверены, что poitners не используются повторно? Если 'sEngine-> addSoundSourceFromFile' дважды возвращает один и тот же указатель, он дважды удаляется, потому что вы назначаете его двум различным' shared_ptr', которые не знают друг о друге.Или, если 'sEngine' вызывает delete на одном из указателей,' shared_ptr' будет нелегко очистить то, чего там нет. Запишите значение указателя, которое вызывает нарушение прав доступа, и попытайтесь сломать любое удаление, которое пытается освободить этот точный адрес. –
'boost :: shared_ptr' имеет функции-члены, которые позволяют вам определить, является ли' shared_ptr' уникальным или получить его счетчик ссылок. – mark