Hi there,
I wish to have an Images singleton object in my program which stores
all my image objects. I then wish to access a particular image via a
unique identifier. To do this, I have created an enum which is equal
in length with the number of images stored in the singleton. I then
use a std::map to store the images with the enum used as the key.
Currently an image contains two strings: a name (used by the image
player) and a file name. An Image object is passed to an ImagePlayer
object elsewhere in my code.
The code I have come up with allows me to check that I am using all
the enum values and that I don't use the same name for an Image more
than once. However, the enum is of course hard coded. Therefore I
can't reuse this code in my other projects which use a different set
of Images, without rewriting the enum.
Have you any ideas how I should solve this problem? Should I give up
on using the enum?
Thanks very much for your help,
Magnus
// Images.h
#pragma once
#include <map>
#include "Image.h"
#define IMAGE_IDS {MOVIE_1, MOVIE_2, MOVIE_3, OLD_MOVIE_1,
OLD_MOVIE_2, SHORT_CLIP}
enum ImageId IMAGE_IDS;
class Images : public std::map<const ImageId, const Image>
{
public:
static Images& Instance();
void LoadIntoImagePlayer() const;
private:
const bool AreAllImageIdsInUse() const;
const bool AreAllImageNamesUnique() const;
};
// Images.cpp
#include "StdAfx.h"
#include <assert.h>
#include <vector>
#include <set>
#include "Images.h"
Images& Images::Instance()
{
static Images images;
return images;
}
const bool Images::AreAllImageIdsInUse() const
{
// make sure that we're using all our enums
const ImageId imageIds[] = IMAGE_IDS;
return this->size()==sizeof(imageIds)/sizeof(ImageId);
}
const bool Images::AreAllImageNamesUnique() const
{
// ensure that all the images have a unique name
std::vector<const Image> images;
std::map<const ImageId, const Image>::const_iterator i=this->begin();
for(;i!=this->end();++i)
images.push_back(i->second);
std::set<const Image> uniqueImageNames(images.begin(),images.end());
return this->size()==uniqueImageNames.size();
}
void Images::LoadIntoImagePlayer() const
{
assert(AreAllImageIdsInUse());
assert(AreAllImageNamesUnique());
//...
}
// Image.h
#pragma once
#include <string>
class Image
{
public:
Image();
Image(const std::string& name, const std::string& fileName);
Image& operator=(const Image&);
const bool operator==(const Image&) const;
const bool operator<(const Image&) const;
const std::string Name() const;
const std::string FileName() const;
private:
std::string m_name;
std::string m_fileName;
};
// Image.cpp
#include "StdAfx.h"
#include "Image.h"
Image::Image()
:m_name(""), m_fileName("")
{
}
Image::Image(const std::string& name, const std::string& fileName)
:m_name(name), m_fileName(fileName)
{
}
Image& Image::operator=(const Image& image)
{
if (this != &image)
{
m_name = image.m_name;
m_fileName = image.m_fileName;
}
return *this;
}
const bool Image::operator==(const Image& image) const
{
return m_name==image.m_name;
}
const bool Image::operator<(const Image& image) const
{
return m_name<image.m_name;
}
const std::string Image::Name() const
{
return m_name;
}
const std::string Image::FileName() const
{
return m_fileName;
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Barry
|
3/21/2010 3:26:52 PM |
|
* Barry:
> Hi there,
>
> I wish to have an Images singleton object in my program which stores
> all my image objects. I then wish to access a particular image via a
> unique identifier. To do this, I have created an enum which is equal
> in length with the number of images stored in the singleton. I then
> use a std::map to store the images with the enum used as the key.
>
> Currently an image contains two strings: a name (used by the image
> player) and a file name. An Image object is passed to an ImagePlayer
> object elsewhere in my code.
>
> The code I have come up with allows me to check that I am using all
> the enum values and that I don't use the same name for an Image more
> than once. However, the enum is of course hard coded. Therefore I
> can't reuse this code in my other projects which use a different set
> of Images, without rewriting the enum.
>
> Have you any ideas how I should solve this problem? Should I give up
> on using the enum?
>
> Thanks very much for your help,
>
> Magnus
>
> // Images.h
> #pragma once
>
> #include <map>
> #include "Image.h"
>
> #define IMAGE_IDS {MOVIE_1, MOVIE_2, MOVIE_3, OLD_MOVIE_1,
> OLD_MOVIE_2, SHORT_CLIP}
>
> enum ImageId IMAGE_IDS;
>
> class Images : public std::map<const ImageId, const Image>
> {
> public:
> static Images& Instance();
> void LoadIntoImagePlayer() const;
>
> private:
> const bool AreAllImageIdsInUse() const;
> const bool AreAllImageNamesUnique() const;
> };
>
> // Images.cpp
> #include "StdAfx.h"
> #include <assert.h>
> #include <vector>
> #include <set>
> #include "Images.h"
>
> Images& Images::Instance()
> {
> static Images images;
> return images;
> }
>
> const bool Images::AreAllImageIdsInUse() const
> {
> // make sure that we're using all our enums
> const ImageId imageIds[] = IMAGE_IDS;
> return this->size()==sizeof(imageIds)/sizeof(ImageId);
> }
>
> const bool Images::AreAllImageNamesUnique() const
> {
> // ensure that all the images have a unique name
> std::vector<const Image> images;
> std::map<const ImageId, const Image>::const_iterator i=this->begin();
> for(;i!=this->end();++i)
> images.push_back(i->second);
> std::set<const Image> uniqueImageNames(images.begin(),images.end());
> return this->size()==uniqueImageNames.size();
> }
>
> void Images::LoadIntoImagePlayer() const
> {
> assert(AreAllImageIdsInUse());
> assert(AreAllImageNamesUnique());
>
> //...
> }
>
> // Image.h
> #pragma once
>
> #include <string>
>
> class Image
> {
> public:
> Image();
> Image(const std::string& name, const std::string& fileName);
> Image& operator=(const Image&);
> const bool operator==(const Image&) const;
> const bool operator<(const Image&) const;
> const std::string Name() const;
> const std::string FileName() const;
>
> private:
> std::string m_name;
> std::string m_fileName;
> };
>
[snip]
Much crucial information missing here, but I'm guessing that the main problem is a procedural approach that is sort of force-fit into C++ classes.
Applying my well known Telepathic Inference Powers (TIP) I surmise that
(1) the purpose of the enum is to identify images with some checking at
compile time, for some usage not even hinted at in the article,
(2) the purpose of the image names-as-strings is to support some code,
perhaps the "player"?, that requires string identifiers, and that
(3) the std::map iterator identification scheme is for iterating through
the images in order to load them into the "player", and perhaps in
order to present them in a menu or something.
Is this correct?
And where do the file names come from?
Are they hard-coded somewhere?
It seems that much of the problem with establishing a class invariant at object construction time is tied in with associating images with file names, combined with a desire to use a singleton. Is this correct? And why the singleton?
Cheers,
- Alf
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Alf
|
3/29/2010 8:21:35 PM
|
|
|
1 Replies
608 Views
(page loaded in 0.058 seconds)
Similiar Articles: std::map< MyString, MyString > comparison operator? - comp.lang ...So the question is, what does <string> implement that <MyString> needs in order to work as a Key in a std::map? Thanks in advance for your help. Loki's AssocVector versus std::map in mt - comp.lang.c++.moderated ...But if I replace the AssocVector with the std::map, I have not yet run into any seg ... Still not sure why the "literal" seg faults, but using an integer key demonstrated ... Finding an int key less than or equal to - comp.lang.c++.moderated ...... key_less_than { public: explicit key_less_than(Key key_comp) : key_comp_(key_comp) { } bool operator()(const typename std::map<Key ... cannot write std::map via ostream_iterator? - comp.lang.c++ ...The ->first points to the key, the ->set points to the data. In your case ... To write std::map via ostream_iterator, it's necessary to have some way to write std ... modify map values through an iterator - comp.lang.c++.moderated ...As > I read the standard, it is not, because an iterator gets you a pair, > and this is a copy of the original values. > > For example, if myMap is std::map<Key, Value ... shared_ptr as map key - comp.lang.c++.moderatedNikola Smiljanić wrote: > Can shared_ptr be used as map key. It has operator< defined ... assignment of std::valarray 1 123 backminator (2) inserting class objects into maps - comp.lang.c++.moderated ...std::map clear throws an exception - comp.lang.c++.moderated ... inserting class ... Insert a pair of object into a map - Stack Overflow Objects that serve as Keys in the map ... comp.lang.c++.moderated... shows my predicament: #include typedef enum ... for a class I am writing so that it can be a key in ... 58:13 AM) Is it legal to mix placement new with a standard ... Differences between multimap and map of vector - comp.lang.c++ ...Hi all, I have to maintain a map with string as a key and several objects referring to the ... not, could someone suggest what differences between AssocVector and std::map ... iterator invalidation guarantees in tr1::unordered_map - comp.lang ...I am trying to transition from gcc's __gnu_cxx::hash_map to std::tr1::unordered_map in ... the container, bucket lists are used to find ranges of objects with the same key ... c++ - Are these appropriate practices when working with std::map ...Having an enum as key_type is not bad by itself. (edit) But if you only use sequential enum-values, a std::vector with O(1) access is even better. enums as values in std::map - C / C++enums as values in std::map. C / C++ Forums on Bytes. ... unset key-values will -always- be 0? thanks for your time, 7/11/2012 1:26:45 PM
|