简体   繁体   English

SDL2 C ++,创建单例时出错

[英]SDL2 C++, Error on creating a singleton

We're following a book called SDL Game Development by Shaun Mitchell which uses SDL2 我们正在关注Shaun Mitchell撰写的一本名为SDL Game Development的书,其中使用了SDL2

We're at the part where we have to create a singleton for a "Texture Manager". 我们需要为“纹理管理器”创建单例。

TextureManager.h TextureManager.h

#include <SDL.h>
#include <SDL_image.h>
#include <string.h>
#include <iostream>
#include <map>
class TextureManager
{
    public:

        bool load(std::string fileName,std::string id,SDL_Renderer* pRenderer);
        void draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
        void drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
        std::map <std::string, SDL_Texture*> m_textureMap;



    protected:
    private:
        TextureManager(){}
        static TextureManager* Instance()
        {
            if(s_pInstance == 0)
            {
                s_pInstance = new TextureManager();
                return s_pInstance;
            }
            return s_pInstance;
        }
        typedef TextureManager TheTextureManager;


};

TextureManager.cpp TextureManager.cpp

#include "TextureManager.h"


TextureManager* TextureManager::s_pInstance = 0;
bool TextureManager::load(std::string fileName, std::string id, SDL_Renderer* pRenderer)
{
    SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
    if(pTempSurface == 0)
    {
        return false;
    }
    SDL_Texture* pTexture =
    SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
    SDL_FreeSurface(pTempSurface);
    // everything went ok, add the texture to our list
    if(pTexture != 0)
    {
        m_textureMap[id] = pTexture;
        return true;
    }
// reaching here means something went wrong
    return false;
}

void TextureManager::draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
    SDL_Rect srcRect;
    SDL_Rect destRect;

    srcRect.x = 0;
    srcRect.y = 0;
    srcRect.w = destRect.w = width;
    srcRect.h = destRect.h = height;
    destRect.x = x;
    destRect.y = y;
    SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
    &destRect, 0, 0, flip);
}

void TextureManager::drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
    SDL_Rect srcRect;
    SDL_Rect destRect;
    srcRect.x = width * currentFrame;
    srcRect.y = height * (currentRow - 1);
    srcRect.w = destRect.w = width;
    srcRect.h = destRect.h = height;
    destRect.x = x;
    destRect.y = y;
    SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect,
    &destRect, 0, 0, flip);
}

The book said to make the constructor a private which we did. 这本书说使我们可以私有化构造函数。
Then followed by declaring static TextureManager* Instance(), which we don't know where to properly declare so we just put it right after the constructor, then it also told us to typedef TextureManager. 然后声明静态的TextureManager * Instance(),我们不知道在哪里正确声明,因此我们将其放在构造函数之后,然后它还告诉我们要输入typedef TextureManager。 Finally it told us to declare TextureManager* TextureManager::s_pInstance = 0; 最后,它告诉我们声明TextureManager * TextureManager :: s_pInstance = 0; on TextureManager.cpp 在TextureManager.cpp上

After following the instruction, we came across an error that says 按照说明进行操作后,我们遇到了一条错误消息:

||=== Build: Debug in Game (compiler: GNU GCC Compiler) ===|
include\TextureManager.h|22|error: 's_pInstance' was not declared in this scope|
include\TextureManager.h|27|error: 's_pInstance' was not declared in this scope|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

The problem is this: 问题是这样的:

//
//TextureManager.cpp
//
TextureManager* TextureManager::s_pInstance = 0;

I don't know why you'd want to do this for any class variable. 我不知道为什么要对任何类变量执行此操作。 Usually, for classes, you would want to put all the variables in the header files that are not local to functions to make it visible to all files that use the header. 通常,对于类,您希望将所有变量放置在函数以外的头文件中,以使其对使用该头的所有文件可见。

It also makes sense that since the variable exists only in the .cpp file, none of the other files that make use of the header will be able to see it. 这也很有意义,因为该变量仅存在于.cpp文件中,因此使用该标头的其他文件将无法看到它。 Therefore, it's as if you never declared it at all in other files, and therefore, you get an undefined reference error: 因此,就好像您从未在其他文件中完全声明过它一样,因此,您会得到未定义的引用错误:

||=== Build: Debug in Game (compiler: GNU GCC Compiler) ===|
include\TextureManager.h|22|error: 's_pInstance' was not declared in this scope|
include\TextureManager.h|27|error: 's_pInstance' was not declared in this scope|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM