object copy with reference

Discussion in 'C++' started by Philipp Kraus, Sep 25, 2011.

  1. Hello,

    I need a tip / hint for solving the following problem:

    I have a class method that is run in different threads:
    myclass::mythreadmethod( mysuperclass& )

    mysuperclass is a reference variable, that is used during the thread is
    running.
    Anyway the method should be myclass::mythreadmethod( mysuperclass ), so that
    each running thread has a own local copy of the object, but I can't
    switch the parameter
    because the method is derivated of another class.

    I need in the method a local (deep-copy) of my object. So I create a
    clone method like
    myclass::mythreadmethod( mysuperclass& pobj )
    {
    mysuperclass& lobj = p_obj.clone();
    }

    In this case I get the compiler error, that I try to set up a temporary
    assignment.

    The try to do it like
    myclass::mythreadmethod( mysuperclass& pobj )
    {
    mysuperclass& lobj;
    p_obj.clone(lobj);
    }
    create the message l_obj isn't initializate.

    Does anyone has some tips to create a working solution? The perfect solution
    should be a deep-copy of the pobj reference

    Thanks

    Phil
    Philipp Kraus, Sep 25, 2011
    #1
    1. Advertising

  2. On 9/25/2011 7:43 AM, Philipp Kraus wrote:
    > I have a class method that is run in different threads:
    > myclass::mythreadmethod( mysuperclass& )


    Is there any relationship between 'myclass' and 'mysuperclass'?

    > mysuperclass is a reference variable, that is used during the thread is
    > running.


    OK, nothing strange here so far.

    > Anyway the method should be myclass::mythreadmethod( mysuperclass ), so
    > that
    > each running thread has a own local copy of the object, but I can't
    > switch the parameter
    > because the method is derivated of another class.


    So, the other class (from which your 'myclass' is derived) requires the
    argument to be a reference to a non-const object. Seems OK. You can
    implement your own

    myclass::mythreadmethod_impl(mysuperclass)

    by overriding the 'mythreadmethod' this way:

    returntype myclass::mythreadmethod(mysuperclass& o)
    {
    mysuperclass local_o(o);
    return this->mythreadmethod_impl(local_o);
    }

    (although, strictly speaking, the creation of local_o isn't necessary,
    it's done here just for illustrating the fact of copying the 'o').

    >
    > I need in the method a local (deep-copy) of my object. So I create a
    > clone method like
    > myclass::mythreadmethod( mysuperclass& pobj )
    > {
    > mysuperclass& lobj = p_obj.clone();
    > }
    >
    > In this case I get the compiler error, that I try to set up a temporary
    > assignment.


    "Temporary assignment"? What's that?

    And what error do you get?

    > The try to do it like
    > myclass::mythreadmethod( mysuperclass& pobj )
    > {
    > mysuperclass& lobj;


    You cannot declare a local object of type reference without initializing
    it. That ought to be flagged by the compiler as an error.

    > p_obj.clone(lobj);
    > }
    > create the message l_obj isn't initializate.
    >
    > Does anyone has some tips to create a working solution? The perfect
    > solution
    > should be a deep-copy of the pobj reference


    See above. It does depend, however, on how 'mysuperclass' is defined.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 25, 2011
    #2
    1. Advertising

  3. On 2011-09-25 15:44:09 +0200, Victor Bazarov said:

    > On 9/25/2011 7:43 AM, Philipp Kraus wrote:
    >> I have a class method that is run in different threads:
    >> myclass::mythreadmethod( mysuperclass& )

    >
    > Is there any relationship between 'myclass' and 'mysuperclass'?


    No, nothing, exception a myclass object calls methods in the
    mysuperclass object.

    >
    > So, the other class (from which your 'myclass' is derived) requires the
    > argument to be a reference to a non-const object. Seems OK. You can
    > implement your own
    >
    > myclass::mythreadmethod_impl(mysuperclass)
    >
    > by overriding the 'mythreadmethod' this way:
    >
    > returntype myclass::mythreadmethod(mysuperclass& o)
    > {
    > mysuperclass local_o(o);
    > return this->mythreadmethod_impl(local_o);
    > }
    >
    > (although, strictly speaking, the creation of local_o isn't necessary,
    > it's done here just for illustrating the fact of copying the 'o').



    That's nice, i will try that. But one question, mysuperclass is a pure
    virtual class, so I can't instanciate it directly (sorry, i've forgot
    this information in my first posting)

    Thanks

    Phil
    Philipp Kraus, Sep 25, 2011
    #3
  4. On 2011-09-25 15:44:09 +0200, Victor Bazarov said:

    > On 9/25/2011 7:43 AM, Philipp Kraus wrote:
    >> I have a class method that is run in different threads:
    >> myclass::mythreadmethod( mysuperclass& )

    >
    > Is there any relationship between 'myclass' and 'mysuperclass'?
    >
    >> mysuperclass is a reference variable, that is used during the thread is
    >> running.

    >
    > OK, nothing strange here so far.
    >
    >> Anyway the method should be myclass::mythreadmethod( mysuperclass ), so
    >> that
    >> each running thread has a own local copy of the object, but I can't
    >> switch the parameter
    >> because the method is derivated of another class.

    >
    > So, the other class (from which your 'myclass' is derived) requires the
    > argument to be a reference to a non-const object. Seems OK. You can
    > implement your own
    >
    > myclass::mythreadmethod_impl(mysuperclass)
    >
    > by overriding the 'mythreadmethod' this way:
    >
    > returntype myclass::mythreadmethod(mysuperclass& o)
    > {
    > => mysuperclass local_o(o); <=
    > return this->mythreadmethod_impl(local_o);
    > }


    the marked => <= call is my problem, bevause mysuperclass is pure
    virtual, so I can't do exactly this. I would like to clone "o"
    (deep-copy) to a local
    variable, but I know that o is a derivate object of mysuperclass. So I
    have add a pure virtual method "clone" to the superclass mysuperclass,
    that
    must be implementated within the derivate class like:

    mysuperclass& local_o = o.clone()

    so local_o gets now a fully own reference to a new o object. The
    problem is the returning type of clone, if I return a mysuperclass& and
    do within
    clone something like
    mysuperclass& clone( void ){
    return myderivateclass; // call the default constructor and
    returns the object with myderivateclass : public mysuperclass
    }
    the compiler breaks with the error temporary assignment, because the
    object is create on the local stack frame and after the clone the
    object is removed.

    If I implementate the clone like
    void clone( mysuperclass& ref) {
    ref = myderivateclass;
    }

    and call the clone in the context:
    mythreadmethod( mysuperclass& o) {
    mysuperclass local_o; //*
    o.clone(local_o);
    }

    the * creates the warning that local_o isn't initialisized, if I use a
    mysuperclass& the compiler create the error, that I can't use
    an empty reference

    Thanks

    Phil
    Philipp Kraus, Sep 25, 2011
    #4
  5. Philipp Kraus

    Goran Guest

    On Sep 25, 5:59 pm, Philipp Kraus <> wrote:
    > On 2011-09-25 15:44:09 +0200, Victor Bazarov said:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On 9/25/2011 7:43 AM, Philipp Kraus wrote:
    > >> I have a class method that is run in different threads:
    > >> myclass::mythreadmethod( mysuperclass& )

    >
    > > Is there any relationship between 'myclass' and 'mysuperclass'?

    >
    > >> mysuperclass is a reference variable, that is used during the thread is
    > >> running.

    >
    > > OK, nothing strange here so far.

    >
    > >> Anyway the method should be myclass::mythreadmethod( mysuperclass ), so
    > >> that
    > >> each running thread has a own local copy of the object, but I can't
    > >> switch the parameter
    > >> because the method is derivated of another class.

    >
    > > So, the other class (from which your 'myclass' is derived) requires the
    > > argument to be a reference to a non-const object.  Seems OK.  You can
    > > implement your own

    >
    > >     myclass::mythreadmethod_impl(mysuperclass)

    >
    > > by overriding the 'mythreadmethod' this way:

    >
    > >     returntype myclass::mythreadmethod(mysuperclass& o)
    > >     {
    > >        => mysuperclass local_o(o); <=
    > >        return this->mythreadmethod_impl(local_o);
    > >     }

    >
    > the marked => <= call is my problem, bevause mysuperclass is pure
    > virtual, so I can't do exactly this. I would like to clone "o"
    > (deep-copy) to a local
    > variable, but I know that o is a derivate object of mysuperclass. So I
    > have add a pure virtual method "clone" to the superclass mysuperclass,
    > that
    > must be implementated within the derivate class like:
    >
    > mysuperclass& local_o = o.clone()
    >
    > so local_o gets now a fully own reference to a new o object. The
    > problem is the returning type of clone, if I return a mysuperclass& and
    > do within
    > clone something like
    > mysuperclass& clone( void ){
    >     return myderivateclass;  // call the default constructor and
    > returns the object with myderivateclass : public mysuperclass}
    >
    > the compiler breaks with the error temporary assignment, because the
    > object is create on the local stack frame and after the clone the
    > object is removed.
    >
    > If I implementate the clone like
    > void clone( mysuperclass& ref) {
    >      ref = myderivateclass;
    >
    > }
    >
    > and call the clone in the context:
    > mythreadmethod( mysuperclass& o) {
    >      mysuperclass local_o;  //*
    >      o.clone(local_o);
    >
    > }
    >
    > the * creates the warning that local_o isn't initialisized, if I use a
    > mysuperclass& the compiler create the error, that I can't use
    > an empty reference


    I think you should take a look at ICloneable in Java and .NET. What
    you want is a copy of an object without knowing its type at
    compilation time. You can add "clone" to abstract your base class,
    however, you must create the object from there, that is, clone()
    should be:

    struct base
    {
    virtual base* clone() const = 0;
    };

    From there, a derived class simply does:

    struct derived : public base
    {
    virtual base* clone() const { return new derived(*this); }
    derived(const derived& rhs) { ... }
    };

    Finally, as I said, you should look at ICloneable. This is because
    "cloning" you need happens so often that it's good to formalize it. It
    requires that you know a base class (there's always one in e.g. Java,
    and in a lot of C++ frameworks, too). So that's a good start, if
    applicable.

    One last thing: since you have threads, copy-construction must be
    thread-safe (i.e, you need a mutex in derived(const derived& rhs)).

    Goran.

    Goran.
    Goran, Sep 26, 2011
    #5
  6. Philipp Kraus

    Qi Guest

    On 2011-9-25 23:59, Philipp Kraus wrote:
    > and call the clone in the context:
    > mythreadmethod( mysuperclass& o) {
    > mysuperclass local_o; //*
    > o.clone(local_o);
    > }
    >
    > the * creates the warning that local_o isn't initialisized, if I use a
    > mysuperclass& the compiler create the error, that I can't use
    > an empty reference


    Usually clone returns an object on the heap.

    MyObject * clone(const MyObject & other) {
    return new MyObject(other);
    }

    If you want to initialize a value, it's better to be "assign".

    void assign(const MyObject & from) {
    this->value = from.value;
    }

    Or vice versa,

    void assignTo(MyObject * to) {
    to->value = this->value;
    }

    Because clone and assign determine the type at runtime,
    you can't return object by value.
    If youc an determine the type at compile time, you don't
    need clone, but just copy the object...


    --
    WQ
    Qi, Sep 26, 2011
    #6
  7. Philipp Kraus

    Werner Guest

    On Sep 25, 1:43 pm, Philipp Kraus <> wrote:
    > Hello,
    >
    > I need a tip / hint for solving the following problem:
    >
    > I have a class method that is run in different threads:
    > myclass::mythreadmethod( mysuperclass& )
    >
    > mysuperclass is a reference variable, that is used during the thread is
    > running.
    > Anyway the method should be myclass::mythreadmethod( mysuperclass ), so that
    > each running thread has a own local copy of the object, but I can't
    > switch the parameter
    > because the method is derivated of another class.
    >
    > I need in the method a local (deep-copy) of my object. So I create a
    > clone method like
    > myclass::mythreadmethod( mysuperclass& pobj )
    > {
    >     mysuperclass& lobj = p_obj.clone();
    >
    > }
    >
    > In this case I get the compiler error, that I try to set up a temporary
    > assignment.
    >
    > The try to do it like
    > myclass::mythreadmethod( mysuperclass& pobj )
    > {
    >     mysuperclass& lobj;
    >    p_obj.clone(lobj);}
    >
    > create the message l_obj isn't initializate.
    >
    > Does anyone has some tips to create a working solution? The perfect solution
    > should be a deep-copy of the pobj reference
    >
    > Thanks
    >
    > Phil


    How about making mysuperclass a pointer (or a smart pointer of some
    kind), then you can initialize it to zero (or in the case of smart_ptr
    it happens automatically). I'd use scoped_ptr in this case..., but as
    example I'd this use a bald pointer...

    struct MySuper
    {
    virtual MySuper* clone() const = 0;

    //... rest of interface

    //... lets not forget this...
    virtual ~MySuper() = 0;
    };



    class Thread
    {
    public:
    Thread();
    ~Thread();
    void associate( MySuper& super );

    private:
    MySuper* super_;
    };

    //x.cpp
    void Thread::associate( MySuper& super )
    {
    super_ = super.clone();
    }

    Thread::Thread()
    : super_() //Don't forget this for bald pointers...
    { }

    Thread::~Thread()
    {
    delete super_;
    }
    Werner, Sep 26, 2011
    #7
  8. Philipp Kraus

    Werner Guest

    On Sep 26, 10:26 am, Werner <> wrote:
    > How about making mysuperclass a pointer (or a smart pointer of some
    > kind), then you can initialize it to zero (or in the case of smart_ptr
    > it happens automatically). I'd use scoped_ptr in this case..., but as
    > example I'd this use a bald pointer...

    [snip]

    I've decided to throw in a smart pointer example too:


    #include <memory>

    struct MySuper
    {
    virtual MySuper* clone() const = 0;

    //... rest of interface

    //... lets not forget this...
    virtual ~MySuper() = 0;
    };



    class Thread
    {
    public:
    Thread();
    ~Thread();
    void associate( MySuper& super );

    private:
    std::auto_ptr<MySuper> super_;
    };

    //x.cpp
    void Thread::associate( MySuper& super )
    {
    super_.reset( super.clone() );
    }

    Thread::Thread()
    { }

    Thread::~Thread()
    {
    }

    I've used auto_ptr in scoped_ptr's stead just because
    for you it might be readily available, whereas scoped_ptr
    (or a version thereof) you can get from www.boost.org, but
    your version of STL might not support scoped_ptr out of the
    box.

    Kind regards,

    Werner
    Werner, Sep 26, 2011
    #8
  9. On 2011-09-26 10:26:23 +0200, Werner said:

    > On Sep 25, 1:43 pm, Philipp Kraus <> wrote:
    >> Hello,
    >>
    >> I need a tip / hint for solving the following problem:
    >>
    >> I have a class method that is run in different threads:
    >> myclass::mythreadmethod( mysuperclass& )
    >>
    >> mysuperclass is a reference variable, that is used during the thread is
    >> running.
    >> Anyway the method should be myclass::mythreadmethod( mysuperclass ), so that
    >> each running thread has a own local copy of the object, but I can't
    >> switch the parameter
    >> because the method is derivated of another class.
    >>
    >> I need in the method a local (deep-copy) of my object. So I create a
    >> clone method like
    >> myclass::mythreadmethod( mysuperclass& pobj )
    >> {
    >>     mysuperclass& lobj = p_obj.clone();
    >>
    >> }
    >>
    >> In this case I get the compiler error, that I try to set up a temporary
    >> assignment.
    >>
    >> The try to do it like
    >> myclass::mythreadmethod( mysuperclass& pobj )
    >> {
    >>     mysuperclass& lobj;
    >>    p_obj.clone(lobj);}
    >>
    >> create the message l_obj isn't initializate.
    >>
    >> Does anyone has some tips to create a working solution? The perfect solution
    >> should be a deep-copy of the pobj reference
    >>
    >> Thanks
    >>
    >> Phil

    >
    > How about making mysuperclass a pointer (or a smart pointer of some
    > kind), then you can initialize it to zero (or in the case of smart_ptr
    > it happens automatically). I'd use scoped_ptr in this case..., but as
    > example I'd this use a bald pointer...


    Thanks, I#M using smart-pointer, i don't see the solution with pointer :p
    Philipp Kraus, Sep 26, 2011
    #9
  10. Philipp Kraus

    Werner Guest

    On Sep 26, 9:02 pm, Philipp Kraus <> wrote:
    > On 2011-09-26 10:26:23 +0200, Werner said:
    >
    >
    >
    > > On Sep 25, 1:43 pm, Philipp Kraus <> wrote:
    > >> Hello,

    >
    > >> I need a tip / hint for solving the following problem:

    >
    > >> I have a class method that is run in different threads:
    > >> myclass::mythreadmethod( mysuperclass& )

    >
    > >> mysuperclass is a reference variable, that is used during the thread is
    > >> running.
    > >> Anyway the method should be myclass::mythreadmethod( mysuperclass ), so that
    > >> each running thread has a own local copy of the object, but I can't
    > >> switch the parameter
    > >> because the method is derivated of another class.

    >
    > >> I need in the method a local (deep-copy) of my object. So I create a
    > >> clone method like
    > >> myclass::mythreadmethod( mysuperclass& pobj )
    > >> {
    > >>     mysuperclass& lobj = p_obj.clone();

    >
    > >> }

    >
    > >> In this case I get the compiler error, that I try to set up a temporary
    > >> assignment.

    >
    > >> The try to do it like
    > >> myclass::mythreadmethod( mysuperclass& pobj )
    > >> {
    > >>     mysuperclass& lobj;
    > >>    p_obj.clone(lobj);}

    >
    > >> create the message l_obj isn't initializate.

    >
    > >> Does anyone has some tips to create a working solution? The perfect solution
    > >> should be a deep-copy of the pobj reference

    >
    > >> Thanks

    >
    > >> Phil

    >
    > > How about making mysuperclass a pointer (or a smart pointer of some
    > > kind), then you can initialize it to zero (or in the case of smart_ptr
    > > it happens automatically). I'd use scoped_ptr in this case..., but as
    > > example I'd this use a bald pointer...

    >
    > Thanks, I#M using smart-pointer, i don't see the solution with pointer :p


    Just be careful of auto_ptr in general. If possible, use scoped_ptr,
    otherwise be sure to overload your copy constructor and assignment
    operator.

    Kind regards,

    Werner
    Werner, Sep 27, 2011
    #10
  11. Philipp Kraus

    Werner Guest

    On Sep 27, 8:34 am, Werner <> wrote:
    > On Sep 26, 9:02 pm, Philipp Kraus <> wrote:
    >
    >
    >
    > > On 2011-09-26 10:26:23 +0200, Werner said:

    >
    > > > On Sep 25, 1:43 pm, Philipp Kraus <> wrote:
    > > >> Hello,

    >
    > > >> I need a tip / hint for solving the following problem:

    >
    > > >> I have a class method that is run in different threads:
    > > >> myclass::mythreadmethod( mysuperclass& )

    >
    > > >> mysuperclass is a reference variable, that is used during the threadis
    > > >> running.
    > > >> Anyway the method should be myclass::mythreadmethod( mysuperclass ),so that
    > > >> each running thread has a own local copy of the object, but I can't
    > > >> switch the parameter
    > > >> because the method is derivated of another class.

    >
    > > >> I need in the method a local (deep-copy) of my object. So I create a
    > > >> clone method like
    > > >> myclass::mythreadmethod( mysuperclass& pobj )
    > > >> {
    > > >>     mysuperclass& lobj = p_obj.clone();

    >
    > > >> }

    >
    > > >> In this case I get the compiler error, that I try to set up a temporary
    > > >> assignment.

    >
    > > >> The try to do it like
    > > >> myclass::mythreadmethod( mysuperclass& pobj )
    > > >> {
    > > >>     mysuperclass& lobj;
    > > >>    p_obj.clone(lobj);}

    >
    > > >> create the message l_obj isn't initializate.

    >
    > > >> Does anyone has some tips to create a working solution? The perfect solution
    > > >> should be a deep-copy of the pobj reference

    >
    > > >> Thanks

    >
    > > >> Phil

    >
    > > > How about making mysuperclass a pointer (or a smart pointer of some
    > > > kind), then you can initialize it to zero (or in the case of smart_ptr
    > > > it happens automatically). I'd use scoped_ptr in this case..., but as
    > > > example I'd this use a bald pointer...

    >
    > > Thanks, I#M using smart-pointer, i don't see the solution with pointer :p

    >
    > Just be careful of auto_ptr in general. If possible, use scoped_ptr,
    > otherwise be sure to overload your copy constructor and assignment
    > operator.
    >
    > Kind regards,
    >
    > Werner


    I meant to say "override" the copy constructor / assignment operator,
    not "overload" (for those who are linguistically pedantic - I realize
    the difference).

    Kind regards,

    Werner
    Werner, Sep 27, 2011
    #11
  12. Philipp Kraus

    SG Guest

    On 27 Sep., 11:08, Werner wrote:
    > On Sep 27, 8:34 am, Werner wrote:
    >
    > > Just be careful of auto_ptr in general. If possible, use scoped_ptr,
    > > otherwise be sure to overload your copy constructor and assignment
    > > operator.

    >
    > I meant to say "override" the copy constructor / assignment operator,
    > not "overload" (for those who are linguistically pedantic - I realize
    > the difference).


    Linguistic pedants would say "declare", I guess. Overriding is
    something specific to virtual functions.

    SG
    SG, Sep 27, 2011
    #12
  13. Philipp Kraus

    Werner Guest

    On Sep 27, 1:10 pm, SG <> wrote:
    > On 27 Sep., 11:08, Werner wrote:
    >
    > > On Sep 27, 8:34 am, Werner wrote:

    >
    > > > Just be careful of auto_ptr in general. If possible, use scoped_ptr,
    > > > otherwise be sure to overload your copy constructor and assignment
    > > > operator.

    >
    > > I meant to say "override" the copy constructor / assignment operator,
    > > not "overload" (for those who are linguistically pedantic - I realize
    > > the difference).

    >
    > Linguistic pedants would say "declare", I guess. Overriding is
    > something specific to virtual functions.
    >
    > SG


    :). Agreed. Declare it, and declare it private (without
    definition) if you want to prohibit copying and assignment,
    or inherit from boost::noncopyable (which shows intent), or
    just use a scoped_ptr, which is not copyable by default.

    Apologies for my lack of linguistic accuracy. Thanks for
    the correction.

    Kind regards,
    Werner, Sep 27, 2011
    #13
    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. VisionSet
    Replies:
    8
    Views:
    4,863
    Tris Orendorff
    Apr 29, 2004
  2. Alex
    Replies:
    2
    Views:
    1,193
  3. nutty
    Replies:
    6
    Views:
    381
    Tom Widmer
    Jun 15, 2006
  4. Replies:
    26
    Views:
    2,074
    Roland Pibinger
    Sep 1, 2006
  5. Replies:
    1
    Views:
    457
    Mark Rae [MVP]
    Sep 20, 2007
Loading...

Share This Page