>>
>> how I can pass data from one container to another container >> both of which are located in different classes?
>>
from the standpoint of container design, generalizing the process of iteration is the key to flexible data transfer. consider the two STL objects vector and list - neither has any 'knowledge' of the existance of or mechanisms governing the other, yet they interoperate rather easily:
Code:
void print(int value) {
cout << value << endl;
}
int main() {
vector <int> svect;
list <int> slist;
for(int i = 0; i < 10; ++i) {
svect.push_back(i);
}
slist.assign(svect.begin(), svect.end());
for_each(slist.begin(), slist.end(), print);
return 0;
}
when the actual objects *themselves* differ, there are several ways you can get them to cooperate with one another. one way is to overload specific member functions to expect the other in assignment (also referred to as 'tight-coupling'):
Code:
struct bar;
struct foo {
foo(int set);
foo(const foo & rhs);
foo(const bar & bar);
int value;
};
struct bar {
bar(int set);
bar(const bar & rhs);
bar(const foo & foo);
int value;
};
foo::foo(int set)
: value(set) {
}
foo::foo(const foo & rhs)
: value(rhs.value) {
}
foo::foo(const bar & bar)
: value(bar.value) {
}
bar::bar(int set)
: value(set) {
}
bar::bar(const bar & rhs)
: value(rhs.value) {
}
bar::bar(const foo & foo)
: value(foo.value) {
}
void printfoo(foo & foo) {
cout << foo.value << endl;
}
int main() {
vector <bar> bvect;
list <foo> flist;
for(int i = 0; i < 10; ++i) {
bvect.push_back(i);
}
flist.assign(bvect.begin(), bvect.end());
for_each(flist.begin(), flist.end(), printfoo);
return 0;
}
another way to do it and have it work with many types of objects is to use member function templates - as long as each object conforms to a specific 'contract' (the syntax for extracting the data), they will interoperate properly:
Code:
struct foo {
template <class T>
foo(const T & object)
: value((int)object) {
}
template <class T>
foo & operator = (const T & object) {
value = (int)object;
return *this;
}
operator int (void) const { /* the contract */
return value;
}
int value;
};
struct bar {
template <class T>
bar(const T & object)
: value((int)object) {
}
template <class T>
bar & operator = (const T & object) {
value = (int)object;
return *this;
}
operator int (void) const { /* the contract */
return value;
}
int value;
};
void print(int value) {
cout << value << endl;
}
int main() {
vector <bar> bvect;
list <foo> flist;
for(int i = 0; i < 10; ++i) {
bvect.push_back(i);
}
flist.assign(bvect.begin(), bvect.end());
for_each(flist.begin(), flist.end(), print);
return 0;
}
using the above example, *any* object that can be casted to an int can be used by foo and bar as a data source - their interfaces are completely decoupled from external objects. this mechanism is very similar to how STL containers interact with eachother actually (ie: generic contracts). the STL is a great source for generic programming techniques, by the way. I'd suggest you get a good reference book on it and study the header files, too.