The following is a toy example:
An image stores a width, height and filepath, represented by the struct
IMAGE
:
#include <cstdlib>
#include <type_traits>
struct IMAGE {
int WIDTH;
int HIGHT;
const char* FILEPATH;
};
static_assert(std::is_pod<IMAGE>::value);
There are a 100 unique IMAGE
s in a game such as a Dirt Block, a Sword, and a Main Menu etc.
One approach (1) to storing all these 100 images in a program is to use separate variables
for each unique image:
int main(){
IMAGE DIRTBLOCK = IMAGE(25, 25, "RESOURCE\\DIRTBLOCKIMAGE");
IMAGE SWORD = IMAGE(100, 25, "RESOURCE\\SWORDIMAGE");
IMAGE MAINMENU = IMAGE(500, 500, "RESOURCE\\MAINMENUIMAGE);
}
Another approach (2) could be to use an enum
of Image Names and an array
of IMAGE
s:
enum IMAGENAME : unsigned char {
DIRTBLOCK,
SWORD,
MAINMENU,
NUMIMAGES
};
IMAGE* IMAGES;
int main(){
IMAGES = (IMAGE*)std::malloc(sizeof(IMAGE) * NUMIMAGES);
IMAGES[DIRTBLOCK] = IMAGE {25, 25, "RESOURCE\\DIRTBLOCKIMAGE"};
IMAGES[SWORD] = IMAGE {100, 25, "RESOURCE\\SWORDIMAGE"};
IMAGES[MAINMENU] = IMAGE {500, 500, "RESOURCE\\MAINMENUIMAGE"};
std::free(IMAGES);
}
Generally, What are the advantages and disadvantages of approaches (1), (2). Alternatively, is there a better approach(3), I have not considered.
I am relatively new to c++, so your help is appreciated.
I came up with a solution based on the suggestion of Ted Lyngmo. I'm not expecting reputation points for this. I only want to show timmy george a possible solution in reasonable C++. Live code.
The container used is an unordered_map
. The IMAGENAME
enum is the key, and IMAGEs
are the value. The container can be walked directly with a range-for
or a standard for
with the addition of the increment()
increasing the value of the enum iterator. Care must be taken not to exceed the range of the enum.
My additional comment is to break from C naming and use a C++ convention. I
would change IMAGENAME
to ImageName
and IMAGE
to Image.
Similarly, rename the enums to DirtBlock
and the member fields to mWidth.
In short, stop shouting in your code. LOL
#include <print>
#include <unordered_map>
using std::println, std::print;
enum IMAGENAME : unsigned char { DIRTBLOCK, SWORD, MAINMENU, NUMIMAGES, LASTIMAGE };
void increment(IMAGENAME& in) {
in = static_cast<IMAGENAME>(static_cast<int>(in) + 1);
}
struct IMAGE {
int WIDTH;
int HEIGHT;
const char* FILEPATH;
};
std::unordered_map<IMAGENAME, IMAGE> images{
{DIRTBLOCK, IMAGE{25, 25, "RESOURCE\\DIRTBLOCKIMAGE"}},
{SWORD, IMAGE{25, 25, "RESOURCE\\SWORDIMAGE"}},
{MAINMENU, IMAGE{25, 25, "RESOURCE\\MAINMENUIMAGE"}},
};
auto main() -> int {
for (auto const& image : images) {
println("{}", image.second.FILEPATH);
}
println("");
for (IMAGENAME in{}; in != NUMIMAGES; increment(in)) {
println("{}", images.at(in).FILEPATH);
}
return 0;
}