PO>I want to be able to efficiently build data structures at run-time.
PO>These data structures need to be accessed with minimal time.
I am working on something similar and have terrible problems
getting it right. I'll explain what I have, tell you where it goes
wrong and hope for someone to fix it.
I use two base classes for everything. The first
is called One, the other Some. One and Some
specialize in a symmetrical way. That is, for every
specialized One there is a corresponding specialized
Some that stores pointers to the specific One's.
The specializations that I made are the following
One <- Sailor
One<- Barrel
One <-Ship
One <- Sea
One <- World
Some <-Sailors
Some <-Barrels
Some <- Ships
Some <-Seas
(Some <-Sailors means class Sailors inherits from class Some)
The hierarchie I build up is petty but it reflects
a real system that I work on. When you
insert Some objects in specialized One objects,
you get a complicated and very dense pack of
interrelated object. Ship contains Sailors and
Barrels, for instance, and a Sea contains many
Ships.
For every Some (Sailors, Barrels, Ships, Seas)
there is the notion of a 'current'. So there is
allways one Sailor current, on the current Ship
in the current Sea. And there is one Barrel
current, on the same ship.
I am not sure if the implementation is right. The
destructor of Some causes problems. There
might be memory leaks. Perhaps someone can
point them out.
Also, I feel that I might slip in a template on this, but
I haven't gotten that far yet.
With a hierarchy similar to this I try to create menu
object dynamically. Four menu headings read
"Sea", "Ship", "Sailor" and "Barrel". They get filled
with data from "Seas", "Ships", "Sailors" and "Barrels"
depending on the current Sea and Ship.
If this code somewhat represents what you want to do, I'd
be honored if you hacked it and show me the weak spots.
-X
#include <iostream.h>
#include <list.h>
class One
{
public:
string name;
string type;
One(const string&a="One",const string&b="One"):name(a),type(b){}
virtual One*get(){return this;}
virtual void show(){cout<<"\n"<<type<<":\t"<<name;}
};
typedef list<One*> More;
class Some
ublic One
{
public:
More more;
size_t index;
Some(const string&a="Some"):One(a,"Some"),index(0){}
Some(const Some&a):One(a),index(a.index)
{
for(More::const_iterator b=a.more.begin();b!=a.more.end();++b)
more.push_back(*b);
}
Some&operator=(const Some&a)
{
index=a.index;
for(More::const_iterator b=a.more.begin();b!=a.more.end();++b)
more.push_back(*b);
return*this;
}
// virtual ~Some()
// {
// for(More::iterator a=more.begin();a!=more.end();++a)
// delete*a;
// }
void showAll()
{
for(More::const_iterator a=more.begin();a!=more.end();++a)
(*a)->show();
}
void add(One*a)
{
more.push_back(a);
}
One * get(){return*(more.begin())+index;}
void next(){if(size()>0)index=index==size()-1?0:index+1;}
void prev(){if(size()>0)index=index==0?size()-1:index-1;}
size_t size(){return more.size();}
void set(int a){index=a<0?index:a>size()-1?index:a;}
};
class Barrel
ublic One{public:Barrel(const string&a):One(a,"Barrel"){}};
class Barrels
ublic Some{};
class Sailor
ublic One{public:Sailor(const string&a):One(a,"Sailor"){}};
class Sailors
ublic Some{};
class Ship
ublic One
{
public:
Sailors sailors;
Barrels barrels;
Ship(const string&a):One(a,"Ship"){}
void show(){One::show();sailors.showAll();barrels.showAll();}
};
class Ships
ublic Some{};
class Sea
ublic One
{
public:
Ships ships;
Sea(const string&a):One(a,"Sea"){}
void show(){One::show();ships.showAll();}
};
class Seas
ublic Some{};
class World
ublic One
{
public:
Seas _seas;
void add(Barrel*a){barrels()->add(a);}
void add(Sailor*a){sailors()->add(a);}
void add(Ship*a){ships()->add(a);}
void add(Sea*a){seas()->add(a);}
void show(){seas()->showAll();}
Barrel * barrel() {return static_cast<Barrel*>(barrels()->get());}
Sailor * sailor() {return static_cast<Sailor*>(sailors()->get());}
Ship * ship() {return static_cast<Ship*>(ships()->get());}
Sea * sea() {return static_cast<Sea*>(seas()->get());}
Barrels * barrels() {return &(ship()->barrels);}
Sailors * sailors() {return &(ship()->sailors);}
Ships * ships() {return &(sea()->ships);}
Seas * seas() {return &_seas;}
};
int main(int argc,char**argv)
{
World world;
Sea sea_1("North Sea");
Sea sea_2("Mare Nostrum");
Ship ship_1("Batavia");
Ship ship_2("New Highland Height");
Ship ship_3("Titanic");
ship_1.sailors.add(new Sailor("Michiel de Ruyter"));
ship_1.sailors.add(new Sailor("Piet Heyn"));
ship_1.barrels.add(new Barrel("Brandewijn"));
ship_1.barrels.add(new Barrel("Whiskey"));
ship_1.barrels.add(new Barrel("Rum"));
ship_2.sailors.add(new Sailor("Mr. Andersson"));
ship_2.sailors.add(new Sailor("Beavis"));
ship_2.sailors.add(new Sailor("Butt-Head"));
ship_2.barrels.add(new Barrel("Cola light"));
ship_2.barrels.add(new Barrel("Milkshake (empty)"));
ship_3.sailors.add(new Sailor("The Flying Dutchman"));
ship_3.barrels.add(new Barrel("Water"));
sea_1.ships.add(&ship_1);
sea_1.ships.add(&ship_2);
sea_2.ships.add(&ship_3);
world._seas.add(&sea_1);
world._seas.add(&sea_2);
world.show();
return 0;
}
_____________________________
Output:
Sea: North Sea
Ship: Batavia
Sailor: Michiel de Ruyter
Sailor: Piet Heyn
Barrel: Brandewijn
Barrel: Whiskey
Barrel: Rum
Ship: New Highland Height
Sailor: Mr. Andersson
Sailor: Beavis
Sailor: Butt-Head
Barrel: Cola light
Barrel: Milkshake (empty)
Sea: Mare Nostrum
Ship: Titanic
Sailor: The Flying Dutchman
Barrel: Water