持有RAII类的类的构造函数调用会导致分段错误

时间:2017-04-19 01:22:26

标签: c++ c++11 constructor segmentation-fault raii

我是新手,我正在学习c ++和一些SFML。 为了测试我的学习,我开始查阅“SFML游戏开发”一书,我从代码中获得了ResourceHolder。

问题在于,当我尝试实现它时,代码确实编译得很好,但它不会执行。经过几个小时的测试和各种问题,我已经到了我认为( Hope )产生最后一个错误的地步。

问题应该是第一个类的初始化,它没有初始化,因为包含的ResourceHolder会导致问题。

的main.cpp

#include "Game.h"

int main(){    
    std::cout << "enter main" << std::endl;`
    Game game;
    std::cout << "after initialization" << std::endl;
}

Game.h

#include "ResourceHolder.h

class Game {
public:
    typedef ResourceHolder<sf::Texture, ID> TextureHolder;
    Game();

private:
    ResourceHolder<sf::Texture, ID> media;        
};

Game.cpp

#include "Game.h"

Game::Game()
{
    std::cout << "initializing game" << std::endl;
}

ResourceHolder.h

#include <map>
#include <string>
#include <memory>
#include <stdexcept>
#include <cassert>
#include <sfml/Graphics.hpp>
#include <iostream>

enum class ID {
    Background,
    Player,
    MAX_ENUM,
};

template <typename Resource, typename Identifier>
class ResourceHolder {
public:
    typedef ResourceHolder<sf::Texture, ID> TextureHolder;
    ResourceHolder()
    {
        TextureHolder texture; //todo <--My guess is here starts the trouble

        std::cout << "here" << std::endl;
        texture.load(ID::Background, "Media/Image1.png");
        texture.load(ID::Player, "Media/Image2.png");

    }

    void load(Identifier id, const std::string& filename);
    Resource& get(Identifier id);
    const Resource& get(Identifier id) const;

private:
    std::map<ID, std::unique_ptr<sf::Texture>> mResourceMap; 
    //The IDE flags this as non-used ^^^
};

#include "ResourceHolder.inl" 

ResourceHolder.inl

template <typename Resource, typename Identifier>
void ResourceHolder<Resource, Identifier>::load(Identifier id, const std::string& filename)
{
    std::unique_ptr<sf::Texture> resource(new Resource());
    if (!resource->loadFromFile(filename))
        throw std::runtime_error("ResourceHolder::load -Failed to load " + filename);
    auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource)));
    assert(inserted.second);
}


template <typename Resource, typename Identifier>
 Resource& ResourceHolder<Resource, Identifier>::get(Identifier id)
{
    auto found = mResourceMap.find(id);
    assert(found != mResourceMap.end());
    return *found->second;
}


template <typename Resource, typename Identifier>
const Resource& ResourceHolder<Resource, Identifier>::get(Identifier id) const
{
    auto found = mResourceMap.find(id);
    assert(found != mResourceMap.end());

    return *found->second;
}

提前致谢!请告诉我,如果我能以任何方式改进这个问题,我担心这可能过于冗长,即使我剥夺了所有不必要的功能和变量。

0 个答案:

没有答案