copying a vector of objects at runtime

J

Julian

Hi,
I have a vector defined like this:
std::vector<Load*> LoadList;
which is populated with different objects of classes that are derived from
'Load'.
I need to make a copy of this list during runtime.
I imagine I'd have to loop through the list, make a copy of each of the
objects in the vector using the copy constructor... but I don't know the
class name during run time so that I can call the appropriate copy
constructor.
actually, I read up on 'typeid' which I supposed would give me the class
name... but I am still confused as how I can call the appropriate copy
constructor for that class during run time.
One option would be to do a string compare of the class names... but that
requires for me to be aware of all the classes derived from 'Load'.
Is there some other way to go about this?
thanks,
Julian.
 
J

Julian

Julian said:
Hi,
I have a vector defined like this:
std::vector<Load*> LoadList;
which is populated with different objects of classes that are derived from
'Load'.
I need to make a copy of this list during runtime.
I imagine I'd have to loop through the list, make a copy of each of the
objects in the vector using the copy constructor... but I don't know the
class name during run time so that I can call the appropriate copy
constructor.
actually, I read up on 'typeid' which I supposed would give me the class
name... but I am still confused as how I can call the appropriate copy
constructor for that class during run time.
One option would be to do a string compare of the class names... but that
requires for me to be aware of all the classes derived from 'Load'.
Is there some other way to go about this?
thanks,
Julian.

I did some more searching and looks like I found the solution from a 10 yr
old post!
http://groups.google.com/group/comp...a75e39ab5004cfc?lnk=st&q=copying+objects+c++#
do let me know if this isn't the right solution
sorry for the inconvenience
 
J

Joe Greer

Hi,
I have a vector defined like this:
std::vector<Load*> LoadList;
which is populated with different objects of classes that are derived
from 'Load'.
I need to make a copy of this list during runtime.
I imagine I'd have to loop through the list, make a copy of each of
the objects in the vector using the copy constructor... but I don't
know the class name during run time so that I can call the appropriate
copy constructor.

Hmmm, if copying the objects in the vector is the answer, then I have to
wonder why there are pointers in the vector to begin with. That is,
wouldn't vector<Load> have been a better place to start? Then copying
would be as simple as LoadList2 = LoadList. IME the only time you
really want a vector of pointers is if the objects have identity
(can't/shouldn't be copied at all) or are horrendously expensive to
copy.

If you still want to copy the vector of pointers (after considering
making them value types instead), you can do something like:

#include <iostream>
#include <sstream>
#include <vector>

template <typename T>
T * clone(T * a)
{
return new T(*a); //assuming copy constructor
}

template <typename T>
class clone_insert_iterator : public std::iterator
<std::eek:utput_iterator_tag, typename T::value_type>
{
T& m_Container;
public:
explicit clone_insert_iterator(T & container) : m_Container
(container) {}
clone_insert_iterator<T> & operator=(typename T::value_type const &
a)
{
m_Container.push_back(clone(a));
return *this;
}
clone_insert_iterator<T> & operator*()
{
return *this;
}
clone_insert_iterator<T> & operator++()
{
return *this;
}
clone_insert_iterator<T> operator++(int)
{
return *this;
}
};


int main()
{
std::vector<int *> v;
std::vector<int *> v1;

v.push_back(new int(5));
v.push_back(new int(1));
v.push_back(new int(10));
v.push_back(new int(7));

clone_insert_iterator<std::vector<int *> > cii(v1);
std::copy(v.begin(), v.end(), cii);

for (int ix = 0; ix < v1.size(); ++ix)
{
std::cout << *v[ix] << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
for (int ix = 0; ix < v1.size(); ++ix)
{
std::cout << *v1[ix] << std::endl;
}
}


Which seems to work, but I made no attempt at robustness nor
completeness for any particular use.


joe
 
S

spacemanspiff

Yes, this is an FAQ:

http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8

Be advised though, this may not be the best solution for you. You should
also look into holding avectorof smart pointers. If that will work for
you (i.e., if it's ok if both vectors actually point to the same set ofobjects,) thencopyingwill be a simple matter of assignment:

vector<smart_ptr<Load> > loadList;vector<smart_ptr<Load> > copy = loadList;

thanks for the response...I will look into smart pointers. but in this
case, I actually want to create a copy of the set of objects. not just
a set of pointers that point to the original set of objects.
I am trying to parallelize some of the steps in my Finite element
analysis program and the reasoning for doing this is so that each
processor can have its own set of objects so that it doesn't cause
conflicts with what the other processor is doing. hope that makes
sense.

Julian.
 
J

Julian

thanks for the response...I will look into smart pointers. but in this
case, I actually want to create a copy of the set of objects. not just
a set of pointers that point to the original set of objects.
I am trying to parallelize some of the steps in my Finite element
analysis program and the reasoning for doing this is so that each
processor can have its own set of objects so that it doesn't cause
conflicts with what the other processor is doing. hope that makes
sense.

Julian.

Sorry for the confusion... i am the original poster. I just started
using Google groups now
 
J

Julian

Hmmm, if copying the objects in the vector is the answer, then I have to
wonder why there are pointers in the vector to begin with.  That is,
wouldn't vector<Load> have been a better place to start?  Then copying
would be as simple as LoadList2 = LoadList.  IME the only time you
really want a vector of pointers is if the objects have identity
(can't/shouldn't be copied at all) or are horrendously expensive to
copy.

I'm not really sure if I understand the first part of your response.
from what I understand (and please let me know if i'm on the wrong
track), vector<Load> can only store only Load objects. even if i try
to store an object of a class derived from Load, it still stores only
a Load object because it calls Load(const Load&) when you do a
push_back.
In my case, I want this vector to 'store' a combination of Load
objects AND other objects that are derived from Load.
hope this helps in describing my situation... and please let me know
if it better for me to use some other c++ strategy.
thanks,
Julian.
 
R

red floyd

Joe said:
Hmmm, if copying the objects in the vector is the answer, then I have to
wonder why there are pointers in the vector to begin with. That is,
wouldn't vector<Load> have been a better place to start? Then copying
would be as simple as LoadList2 = LoadList. IME the only time you
really want a vector of pointers is if the objects have identity
(can't/shouldn't be copied at all) or are horrendously expensive to
copy.

You forgot the other case, where your vector contains polymorphic
objects. But then you should probably be using a container of your
favorite smart pointer.
 
J

Joe Greer

I'm not really sure if I understand the first part of your response.
from what I understand (and please let me know if i'm on the wrong
track), vector<Load> can only store only Load objects. even if i try
to store an object of a class derived from Load, it still stores only
a Load object because it calls Load(const Load&) when you do a
push_back.
In my case, I want this vector to 'store' a combination of Load
objects AND other objects that are derived from Load.
hope this helps in describing my situation... and please let me know
if it better for me to use some other c++ strategy.
thanks,
Julian.

Ah yes, I forgot polymorphism... In that case, if your objects have
identity, that is, you really only want one instance of it, then you might
look at a smart_ptr (from either TR1 or boost) to manage lifetime of the
object and just copy the vector normally. Or you make your Load interface
contain a clone() method of some sort which has the object create a copy of
itself. A clone_inserter iterator can then be made which invokes this
method to get the clone of the object and use std::copy() as I described
elsewhere.

joe
 
J

Joe Greer

You forgot the other case, where your vector contains polymorphic
objects. But then you should probably be using a container of your
favorite smart pointer.

Yep. Somehow, the way the question was worded, It didn't occur to me that
these were pointers to a base/interface. Sigh.

joe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top