Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# nested dynamic data structure

Posted on 2002-04-10
Medium Priority
287 Views
I have a possible need to use a nested dynamic data structure and was wondering if there is a common or well known approach to designing one.

I have data in 14 different kinds of blocks where each block contains several data types. I can have a variable
amount of 6 of these blocks.

The set of 14 blocks itself is a block which I will have
a varied amount.

I was going to make structures for each of the 14 blocks to handle the different data types in each type of block,
but I'm not sure how to encompass a set of variable length list of these structures.

unfortunately I didn't run into anything like this while going to school.

I wanted to see if someone could point me in the right direction with links to references of similiar problems or a description of how one might tackle this problem.
0
Question by:mitchguy
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 7
• 6
• 4

LVL 30

Expert Comment

ID: 6932962
Your explanation is a little ambiguous.

Could you provide an example of what you're trying to do?
0

Author Comment

ID: 6932985
an analogy to what I'm trying to do would be if I needed
to keep records for a dynamic list of people. If each person can have nickels, dimes and pennies. I need to add  new people as they come and each person can add nickels, dimes and pennies as much as they want. A variable length lists of variable length list.

Hope this helps, it's the best I can think of with out going into the details of my work.
0

LVL 2

Expert Comment

ID: 6933760
I don't think there is a standard pattern, if thats what you're after. Typically, you would use a container that keeps a (variable) "list" of references to the actual objects. The objects themselves could then contain (once again a variable) "list" of references to other objects and so on. The "lists" could be hashmaps, deque's or whatever, depending on your needs. All this is provided in the STL so you have to do precious little to set up such a structure. With the STL functionality you cab have many layers of dynamic structures, as you call it.

The only thing you have to be careful of is keeping track of who creates and destroys the objects if you want to use pointers to objects in stead of the actual objects.

I don't know if this answers your question. If not, just shout
0

LVL 30

Expert Comment

ID: 6933792
mitchguy,
You can do this, but you have to have a common interface.
0

LVL 30

Expert Comment

ID: 6933802
Example of a common interface class:

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

class Xyz
{
public:
int x;
int y;
int z;
void OnTrigger(void)
{
cout << "Xyz" << endl;
}
};

class Abc
{
public:
string SomeStr;
void OnTrigger(void)
{
cout << "Abc" << endl;
}
};

class FooFoo
{
public:
void OnTrigger(void)
{
cout << "FooFoo" << endl;
}
};

class PureVirtualClass
{
public:
virtual void OnTrigger(void)=0;
};

template<typename T>
class TargetClassHolder : public PureVirtualClass
{
public:
TargetClassHolder(T &Src)
{
TargetClass = &Src;
}
void OnTrigger(void)
{
TargetClass->OnTrigger();
}
T *TargetClass;
};

class CHandleTrigger
{
public:
template<typename T>
void Register(T& Src)
{
m_Targets.push_back(new TargetClassHolder<T>(Src));
}
void RunAllTriggers(void)
{
for(vector<PureVirtualClass*>::iterator i = m_Targets.begin();i != m_Targets.end();++i)
{
(*i)->OnTrigger();
}
}
static bool DeleteAndNullifyIterator(PureVirtualClass *& pObj)
{
delete pObj;
pObj = NULL;
return true;
}
~CHandleTrigger()
{//Delete the TargetClassHolder(s).  This does NOT delete the actual target class, only the TargetClassHolder
m_Targets.erase(remove_if(m_Targets.begin(), m_Targets.end(),CHandleTrigger::DeleteAndNullifyIterator), m_Targets.end());
}
private:
//can do this here with any class derived from Trigger_vir
vector<PureVirtualClass*> m_Targets;
};

int main(int argc, char* argv[])
{
Abc abc;
Xyz xyz;
FooFoo foofoo;
CHandleTrigger MyTriggerHandler;
MyTriggerHandler.Register(abc);
MyTriggerHandler.Register(xyz);
MyTriggerHandler.Register(foofoo);
MyTriggerHandler.RunAllTriggers();

system("pause");
return 0;
}

0

LVL 30

Expert Comment

ID: 6933814
With the above example, class CHandleTrigger is able to add any class to  m_Targets, which has an OnTrigger member function.
So the common interface for the above example is the OnTrigger member function.
0

Author Comment

ID: 6934623
LoungeLizard,
why is it better to use pointers than the object itself?

So if I want to add a new record I need to get a new object and a new pointer or would it be better to encapsulate a pointer in the object itself.
0

LVL 30

Expert Comment

ID: 6934654
mitchguy,
Did you look at the code I posted?

CHandleTrigger is able to store a pointer to any object, as long as that object has a common interface.
0

Author Comment

ID: 6935283
Axter, is your code meant for visual c++?
I'm programming on Linux
0

LVL 30

Expert Comment

ID: 6935300
>>Axter, is your code meant for visual c++?

My code is for any standard C++ compiler.  Including Linux.

The only non-portable part of the code is system("pause"), which you can exclude, since it has nothing to do with the class examples.
0

LVL 2

Expert Comment

ID: 6935519
>>why is it better to use pointers than the object itself?

Well, it is not neccesarily better, but more often than not the same objects are used in various places, and then you create the object only once and refer to (either by pointer (*) or reference (&)) afterwards in stead of making local copies everytime you need it. In case of complex objects this would represent a signficant saving in terms of speed and memory
0

Author Comment

ID: 6935528
Axter,
I'm a little confused on how I can apply what you've
shown me to my problem. Lets say I have a file with the following data:
person1
N N N N N N D D D D D P P
person2
N N N D D P
person3
N D D P P P P
.
.
.
personN
N...D....P...

Where N, D and P are Nickels, Dimes and Pennies and there
can be any number of these in a row.

Would each person be a class in your example?
If Xyz's data members in your example were changed to
int D;
int N;
int P;
how could I store more than one of each type,
Or would D, N and P be classes?

Ideally I would like to insert any new person and their
data anywhere in my list.

0

LVL 2

Accepted Solution

LoungeLizard earned 600 total points
ID: 6935604
Simple implementation using STL

#include <list>

class nickel
{
};

class dime
{
};

class penny
{
};

class person
{
public:

void removeLastNickel() {myNickels.erase(myNickels.end());}
void removeLastDime() {myDimes.erase(myDimes.end());}
void removeLastPenny() {myPennies.erase(myPennies.end());}

private:
list<nickel *> myNickels;
list<dime *> myDimes;
list<penny *> myPennies;
};

class group
{
public:

void removeLastPerson() {myPersons.erase(myPersons.end());}

private:
list<person *> myPersons;
};

main()
{
person p1, p2, p3;
nickel n1, n2;
dime d1, d2;
penny pn1, pn2;
group myGroup;

// etc...

}

See more of the STL here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcstdlib/html/vcoriStandardCLibraryReference.asp

0

Author Comment

ID: 6935945
Lounge lizard,
int n;
inside of class nickel
how would I print that value out.
here's what I tried , but I just get an address.
n1.five = 5;
n2.five = 6;
n3.five = 7;

std::list <person *>::iterator ptr;
ptr = myGroup.myPersons.begin();
while(ptr != myGroup.myPersons.end()){
cout<<"person has "<<*ptr<<endl;
ptr++;
}
0

LVL 2

Expert Comment

ID: 6935977
I'm not exactly sure what you want to do. Do you want to know how many nickels each person has, or do you want to add a value to the class nickel that you can manually modify?

Anyway, you are using the iterator incorrectly. *ptr will return the CONTENTS of the position in the list where the iterator is pointing to.

Since we have pointers in our list, that means you get a pointer. If you want to print something, you'll have to use (*ptr)->somePrintValue
0

LVL 30

Expert Comment

ID: 6935994
This is an example using the code I posted previously.

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

class Penny
{
public:
int GetValue()
{
return 1;
}
};

class Nickel
{
public:
int GetValue()
{
return 5;
}
};

class Dime
{
public:
int GetValue()
{
return 10;
}
};

class Coins
{
public:
virtual int GetValue()=0;
};

template<typename T>
class TargetClassHolder : public Coins
{
public:
TargetClassHolder(T &Src)
{
TargetClass = &Src;
}
int GetValue()
{
return TargetClass->GetValue();
}
T *TargetClass;
};

class Person
{
public:
template<typename T>
{
m_Targets.push_back(new TargetClassHolder<T>(Src));
}
int GetTotal()
{
int Total = 0;
for(vector<Coins*>::iterator i = m_Targets.begin();i != m_Targets.end();++i)
{
Total += (*i)->GetValue();
}
}
static bool DeleteAndNullifyIterator(Coins *& pObj)
{
delete pObj;
pObj = NULL;
return true;
}
~Person()
{//Delete the TargetClassHolder(s).  This does NOT delete the actual target class, only the TargetClassHolder
m_Targets.erase(remove_if(m_Targets.begin(), m_Targets.end(),Person::DeleteAndNullifyIterator),
m_Targets.end());
}
private:
//can do this here with any class derived from Trigger_vir
vector<Coins*> m_Targets;
};

int main(int argc, char* argv[])
{
Penny penny;
Nickel nickel;
Dime dime;
Person MyTriggerHandler;
int Total = MyTriggerHandler.GetTotal();
cout << "Total = " << Total << endl;

system("pause");
return 0;
}

0

Author Comment

ID: 6936019
Thank you both for all of your help. I will post some points for you also Axter.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. â€¦
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why tâ€¦
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor anâ€¦
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
###### Suggested Courses
Course of the Month7 days, 15 hours left to enroll