How to copy a vector if pointers to base class

Discussion in 'C++' started by Alex Snast, Jun 8, 2008.

  1. Alex Snast

    Alex Snast Guest

    hello

    I'm trying to implement a copy constructor for a vector of pointers to
    a base class (which is abstract)

    My question is how would i know what kind of new type should i
    allocate since the base poiner can have multipull meanings.

    i know i can use dynamic_cast however i really don't like this
    solution and i was wondering is i can do something better

    thanks
    Alex Snast, Jun 8, 2008
    #1
    1. Advertising

  2. Alex Snast

    Kai-Uwe Bux Guest

    Alex Snast wrote:

    > hello
    >
    > I'm trying to implement a copy constructor for a vector of pointers to
    > a base class (which is abstract)
    >
    > My question is how would i know what kind of new type should i
    > allocate since the base poiner can have multipull meanings.
    >
    > i know i can use dynamic_cast however i really don't like this
    > solution and i was wondering is i can do something better


    The standard trick is to provide a virtual clone() member in the base class.
    You can then copy the vector by using std::transform with a back_inserter
    and a functor like this

    Base* deep_copy ( Base * ptr ) {
    return( ptr->clone() );
    }

    or some of these unreadable pointer to member function binders.

    You can also google the archives for copy_ptr or clone_ptr to find smart
    pointers with deep copy semantics. Those are non-standard and might make
    your code harder to maintain for others since they might not be familiar
    with those libraries. On the plus side, you don't need to do anything to
    copy a vector of those since the copy constructor of the smart pointer will
    to the job.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Jun 8, 2008
    #2
    1. Advertising

  3. Alex Snast

    Alex Snast Guest

    Kai-Uwe Bux כתב:
    > Alex Snast wrote:
    >
    > > hello
    > >
    > > I'm trying to implement a copy constructor for a vector of pointers to
    > > a base class (which is abstract)
    > >
    > > My question is how would i know what kind of new type should i
    > > allocate since the base poiner can have multipull meanings.
    > >
    > > i know i can use dynamic_cast however i really don't like this
    > > solution and i was wondering is i can do something better

    >
    > The standard trick is to provide a virtual clone() member in the base class.
    > You can then copy the vector by using std::transform with a back_inserter
    > and a functor like this
    >
    > Base* deep_copy ( Base * ptr ) {
    > return( ptr->clone() );
    > }
    >
    > or some of these unreadable pointer to member function binders.
    >
    > You can also google the archives for copy_ptr or clone_ptr to find smart
    > pointers with deep copy semantics. Those are non-standard and might make
    > your code harder to maintain for others since they might not be familiar
    > with those libraries. On the plus side, you don't need to do anything to
    > copy a vector of those since the copy constructor of the smart pointer will
    > to the job.
    >
    >
    > Best
    >
    > Kai-Uwe Bux


    Thanks for the help. Worked just find even though i haven't used
    std::transform but rather wrote my own method
    Storerepository::Storerepository(const Storerepository& rhs)
    throw(OutOfMemory)
    {
    try {
    for (const_repertory_iterator cit = rhs.repertory_.begin(); cit !=
    rhs.repertory_.end(); ++cit) {
    this->repertory_.push_back((*cit)->clone());
    }
    }
    catch(std::bad_alloc){
    throw OutOfMemory();
    }
    }

    thanks again'
    Alex Snast, Jun 8, 2008
    #3
  4. Hi!

    Daniel T. schrieb:
    > Or:
    >
    > transform(rhs.repertory_.begin(), rhs.repertory_.end(),
    > back_inserter(repertory_), mem_fun(&Base::clone));


    The mem_fun will not do virtual dispatch here! But you can always do it
    like the "C++ Conding Standards" say: have a public non-virtual function
    which calls the virtual protected function. Then the above would work.

    class Base {
    public:
    Base* clone() const { return doClone(); }
    protected:
    virtual Base* doClone()=0;
    };

    Frank
    Frank Birbacher, Jun 9, 2008
    #4
  5. Alex Snast

    James Kanze Guest

    On Jun 9, 1:02 pm, Frank Birbacher <> wrote:
    > Daniel T. schrieb:


    > > Or:


    > > transform(rhs.repertory_.begin(), rhs.repertory_.end(),
    > > back_inserter(repertory_), mem_fun(&Base::clone));


    > The mem_fun will not do virtual dispatch here!


    The mem_fun has exactly the same semantics of calling the
    function directly; if the function is declared virtual in Base,
    and you call it correctly with a pointer to the base, then it
    will use virtual dispatch.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 9, 2008
    #5
  6. Hi!

    James Kanze schrieb:
    >> The mem_fun will not do virtual dispatch here!

    >
    > The mem_fun has exactly the same semantics of calling the
    > function directly;


    This is nothing a boost::bind could do, right? The mem_fun has extra
    help from the compiler here, right?

    > if the function is declared virtual in Base,
    > and you call it correctly with a pointer to the base, then it
    > will use virtual dispatch.


    So, the following won't do the same?

    struct Base {
    virtual void foo() {}
    };

    struct Dev : Base {
    void foo() {}
    void test();
    };

    void Dev::test() {
    using boost::bind;

    this->Base::foo(); //calls Base::foo
    this->*(&Base::foo)(); //calls Base::foo ??
    mem_fun(&Base::foo)(this); //calls Dev::foo ?? WTF?
    bind(&Base::foo, this)(); //calls Base::foo ??
    }

    I don't get it. How does mem_fun work?

    Frank
    Frank Birbacher, Jun 9, 2008
    #6
  7. Alex Snast

    James Kanze Guest

    On Jun 9, 3:31 pm, Frank Birbacher <> wrote:
    > James Kanze schrieb:


    > >> The mem_fun will not do virtual dispatch here!


    > > The mem_fun has exactly the same semantics of calling the
    > > function directly;


    > This is nothing a boost::bind could do, right? The mem_fun has
    > extra help from the compiler here, right?


    No extra help. It uses a pointer to member function.

    > > if the function is declared virtual in Base, and you call it
    > > correctly with a pointer to the base, then it will use
    > > virtual dispatch.


    > So, the following won't do the same?


    > struct Base {
    > virtual void foo() {}
    > };


    > struct Dev : Base {
    > void foo() {}
    > void test();
    > };


    > void Dev::test() {
    > using boost::bind;


    > this->Base::foo(); //calls Base::foo
    > this->*(&Base::foo)(); //calls Base::foo ??


    Doesn't compile.
    (this->*(&Base::foo))() ;
    calls Dev::foo.

    > mem_fun(&Base::foo)(this); //calls Dev::foo ?? WTF?


    Calls Dev::foo.

    > bind(&Base::foo, this)(); //calls Base::foo ??


    Calls Dev::foo.
    > }


    > I don't get it. How does mem_fun work?


    It uses a pointer to member function.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jun 10, 2008
    #7
  8. Hi!

    Daniel T. schrieb:
    > The output I get is:
    >
    > Base::foo()
    > Dev::foo()
    > Dev::foo()
    > Dev::foo()
    >
    > IE: in every case except the first, Dev::foo() is called.


    o_O I'm sorry, I have a complete misunderstanding of this issue.

    Thanks to both of you, Daniel and James, for clearing things up.

    Frank
    Frank Birbacher, Jun 10, 2008
    #8
    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. Alf P. Steinbach
    Replies:
    6
    Views:
    530
    John Carson
    Sep 3, 2005
  2. Replies:
    8
    Views:
    1,889
    Csaba
    Feb 18, 2006
  3. Victor Bazarov
    Replies:
    15
    Views:
    750
    Greg Comeau
    Mar 4, 2007
  4. tech
    Replies:
    2
    Views:
    529
    terminator
    Jul 15, 2008
  5. Hicham Mouline
    Replies:
    1
    Views:
    577
    Victor Bazarov
    Apr 20, 2009
Loading...

Share This Page