Ich versuche, so etwas wie ein Java-Stil Enum zu machen, die ich ein Flag nennen. Die Anforderungen sind, dass jede Flagge statisch ist, so dass Flaggen direkt referenzierbar sind, jede Flagge speichert die Zeichenfolge des Namens und die ganze Menge iterable und förderlich für Lookups.
Ich verwende Templating, so dass jeder Satz von Flaggen separat gespeichert wird (so sparen Sie mich von explizit einen Satz in jeder Kindklasse zu platzieren).
Ich bin davon überzeugt, dass es sich um ein Initiierungsproblem handelt, da der Erfolg oder Misserfolg der Ausführung des Programms vom Dateinamen der Objektdatei abhängt, die die Flag-Deklarationen enthält (A.o schlägt fehl, aber Z.o läuft einwandfrei).
Das Problem scheint eine der statischen Initialisierungsreihenfolge zu sein, dieser Code kompiliert völlig in Ordnung, aber wenn es ausgeführt wird, produziert gdb das folgende:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff751e0fa in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) ()
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/libstdc++.so.6
(gdb) bt
#0 0x00007ffff751e0fa in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) ()
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/libstdc++.so.6
#1 0x0000000000462669 in operator-- ()
at /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4/bits/stl_tree.h:199
#2 _M_insert_unique ()
at /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4/bits/stl_tree.h:1179
#3 insert () at /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4/bits/stl_set.h:411
#4 Flag () at include/../util/include/Flag.hpp:34
#5 ItemFlag () at include/Item.hpp:22
#6 __static_initialization_and_destruction_0 () at Item.cpp:15
#7 global constructors keyed to _ZN3code8ItemFlag5brickE() () at Item.cpp:86
#8 0x000000000046ac62 in ?? ()
#9 0x00007fffffffddc0 in ?? ()
#10 0x000000000046abb0 in ?? ()
#11 0x0000000000692c0a in ?? ()
#12 0x0000000000407693 in _init ()
#13 0x00007ffff7dded08 in ?? () from /usr/lib64/libboost_serialization-1_42.so.1.42.0
#14 0x000000000046abe7 in __libc_csu_init ()
#15 0x00007ffff6cd9b50 in __libc_start_main () from /lib64/libc.so.6
#16 0x0000000000408329 in _start ()
Mein Code lautet wie folgt:
template <class FlagType> class Flag
{
public:
Flag(int ordinal, String name):
ordinal(ordinal),
name(name)
{
flagSet.insert(this);
}
inline bool operator==(const Flag<FlagType>& e) const
{
//edited due to comment
//if(this->ordinal == e.getOrdinal()) return true;
//else return false;
return (this->ordinal == e.getOrdinal());
}
inline bool operator!=(const Flag<FlagType>& e) const
{
return !(*this==e);
}
static const std::set<const Flag<FlagType>*>& flagValues()
{
return flagSet;
}
const String& toString() const
{
return name;
}
const size_t& getOrdinal() const
{
return ordinal;
}
static int size()
{
return flagSet.size();
}
static const Flag<FlagType>& valueOf(const String& string)
{
typename std::set<const Flag<FlagType>*>::const_iterator i;
for(i = flagSet.begin(); i != flagSet.end(); i++)
{
if((**i).toString().startsWith(string))
{
return **i;
}
}
throw NotAFlagException();
}
protected:
static std::set<const Flag<FlagType>*> flagSet;
size_t ordinal;
String name;
private:
//added in response to comment to prevent copy and assignment, not compile tested
Flag<FlagType>(const Flag<FlagType>&);
Flag<FlagType>& operator=(const Flag<FlagType>&);
};
template <class FlagType> std::set<const Flag<FlagType>*> Flag<FlagType>::flagSet; //template
Artikel.hpp
class ItemFlag: public Flag<ItemFlag>
{
public:
static const ItemFlag brick;
private:
ItemFlag(int ordinal, String name):
Flag<ItemFlag>(ordinal, name){}
};
Element.cpp
const ItemFlag ItemFlag::brick(1, "brick");
Dies ist mein erster Beitrag, also lassen Sie mich bitte wissen, ob ich die Formatierung falsch gemacht habe oder unspezifisch war. PS. Seltsamerweise führt das Ersetzen von set durch vector zu einem funktionierenden Programm, als ob das set Probleme mit dem Einfügen der Zeiger hat. Um dies zu testen, habe ich das Set durch ein Set von int ersetzt und versucht, bei der Klasseninitialisierung 0 einzufügen, was ebenfalls zu demselben Fehler führte.