copying a vector of objects at runtime

Discussion in 'C++' started by Julian, Jul 10, 2008.

  1. Julian

    Julian Guest

    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.
     
    Julian, Jul 10, 2008
    #1
    1. Advertising

  2. Julian

    Julian Guest

    "Julian" <> wrote in message
    news:g54akk$c32$...
    > 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
     
    Julian, Jul 10, 2008
    #2
    1. Advertising

  3. Julian

    Joe Greer Guest

    "Julian" <> wrote in
    news:g54akk$c32$:

    > 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
     
    Joe Greer, Jul 10, 2008
    #3
  4. On Jul 10, 9:46 pm, "Daniel T." <> wrote:
    > "Julian" <> wrote:
    > > "Julian" <> wrote:
    > > > I have avectordefined like this:
    > > > std::vector<Load*> LoadList;
    > > > which is populated with differentobjectsof 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
    > > >objectsin thevectorusing 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.lang.c /browse_thread/thread/1d4...
    > > 35d0/ea75e39ab5004cfc?lnk=st&q=copying+objects+c%2B%2B#
    > > do let me know if this isn't the right solution
    > > sorry for the inconvenience

    >
    > 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.
     
    spacemanspiff, Jul 11, 2008
    #4
  5. Julian

    Julian Guest

    On Jul 10, 11:35 pm, spacemanspiff <> wrote:
    > On Jul 10, 9:46 pm, "Daniel T." <> wrote:
    >
    >
    >
    > > "Julian" <> wrote:
    > > > "Julian" <> wrote:
    > > > > I have avectordefined like this:
    > > > > std::vector<Load*> LoadList;
    > > > > which is populated with differentobjectsof 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
    > > > >objectsin thevectorusing 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.lang.c /browse_thread/thread/1d4....
    > > > 35d0/ea75e39ab5004cfc?lnk=st&q=copying+objects+c%2B%2B#
    > > > do let me know if this isn't the right solution
    > > > sorry for the inconvenience

    >
    > > 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.


    Sorry for the confusion... i am the original poster. I just started
    using Google groups now
     
    Julian, Jul 11, 2008
    #5
  6. Julian

    Julian Guest

    On Jul 10, 10:02 am, Joe Greer <> wrote:
    > "Julian" <> wrote innews:g54akk$c32$:
    >
    > > 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.
    >


    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.
     
    Julian, Jul 11, 2008
    #6
  7. Julian

    red floyd Guest

    Joe Greer wrote:
    > "Julian" <> wrote in
    > news:g54akk$c32$:
    >
    >> 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.
    >


    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.
     
    red floyd, Jul 11, 2008
    #7
  8. Julian

    Joe Greer Guest

    Julian <> wrote in
    news::

    > On Jul 10, 10:02 am, Joe Greer <> wrote:
    >> "Julian" <> wrote
    >> innews:g54akk$c32$:
    >>

    >
    > 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
     
    Joe Greer, Jul 11, 2008
    #8
  9. Julian

    Joe Greer Guest

    red floyd <> wrote in
    news:qiCdk.12091$:

    > Joe Greer wrote:
    >> "Julian" <> wrote in
    >> news:g54akk$c32$:
    >>
    >>> 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.
    >>

    >
    > 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
     
    Joe Greer, Jul 11, 2008
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. pmatos
    Replies:
    6
    Views:
    23,821
  2. Replies:
    8
    Views:
    1,930
    Csaba
    Feb 18, 2006
  3. Jess
    Replies:
    9
    Views:
    410
  4. Javier
    Replies:
    2
    Views:
    568
    James Kanze
    Sep 4, 2007
  5. Rushikesh Joshi
    Replies:
    0
    Views:
    366
    Rushikesh Joshi
    Jul 10, 2004
Loading...

Share This Page