不能将push_back()结构转换为std :: vector <std :: shared_ptr <thestruct>&gt; theVector

时间:2017-07-05 21:06:20

标签: c++

希望我的头衔不会太混乱。我正在尝试使用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/fa684f2f2d5ehttps://bpaste.net/show/c74ac701ce7a,代码按预期工作。任何想法都赞赏!

1 个答案:

答案 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必须重新分配内存并失败时,它可能导致内存泄漏。