简体   繁体   中英

How to initialize all variables from a namespace in one class

I am making a small game using SFML. I want to load all my resources in one go when the game launches, so every time a new entity is created new resources don't need to be loaded to memory slowing down the game.

I have made a header file with a namespace for each kind of resource I need:

#pragma once

#include <SFML/Graphics.hpp>

#include <iostream>

#include "spritesheet.h"

namespace PlayerSprite {
    extern Spritesheet playerSpritesheet;
    extern sf::Sprite sp1, sp2, sp3, sp4, sp5, sp6;
    extern int width = 16;
    extern int height = 16;
}

namespace ButtonSprite {
    extern Spritesheet buttonSpritesheet;
    extern sf::Sprite button;
    extern int width = 32;
    extern int height = 16;
}

class Resources {
    public:
        Resources() = default;
        void loadResources();
};

Now I don't know much about namespaces only very basic stuff, this is the first reason to use one.

Now in the cpp file:

#include <iostream>

#include "../headers/resources.h"

void Resources::loadResources() {
    // PLAYER
    PlayerSprite::playerSpritesheet.setSprite("./res/img/tiles.png");
    PlayerSprite::sp1 = PlayerSprite::playerSpritesheet.getSprite(0, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp2 = PlayerSprite::playerSpritesheet.getSprite(32, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp3 = PlayerSprite::playerSpritesheet.getSprite(48, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp4 = PlayerSprite::playerSpritesheet.getSprite(64, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp5 = PlayerSprite::playerSpritesheet.getSprite(80, 0, PlayerSprite::width, 
    PlayerSprite::height);
    PlayerSprite::sp6 = PlayerSprite::playerSpritesheet.getSprite(0, 16, PlayerSprite::width, 
    PlayerSprite::height);
    // PLAYER

    // BUTTONS
    ButtonSprite::buttonSpritesheet.setSprite("./res/img/tiles.png");
    ButtonSprite::button = ButtonSprite::buttonSpritesheet.getSprite(48, 16, 32, 16);
    // BUTTONS
}

I then call this function in the main game file, but when I run I get this error in the player class:

undefined reference to 'PlayerSprite:sp1'

I don't know if this is because of the namespace declaration, or me coding the system wrong.


After looking at some comments on this question I have added this:

void Resources::allocateStorage() {
    sf::Sprite PlayerSprite::spritesheet;
    sf::Sprite PlayerSprite::sp1;
}

In the cpp file, but I am now getting this error:

unqualified-id in declaration before ';' token unqualified-id in declaration before ';' token on the 1st line after the implementation of the function.

The problem seems to be that the variables are not actually defined anywhere, just declared. When using extern , the compiler will assume that this variable exists, so the compiler can continue on assuming that the variable exists. The linker will then come in, and see where that variable exists. If it does not, you get an undefined reference error. To fix this, you need to define the variables somewhere.

For example, in say resources.cpp , you would have:

#include "../headers/resources.h"

sf::Sprite PlayerSpriter::sp1;
sf::Sprite PlayerSpriter::sp2;
sf::Sprite PlayerSpriter::sp3;
// etc...


void Resources::loadResources() { 
    // …
}

This is in addition to what you already have in your header.

NOTE: From your edit, this would occur outside any function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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