DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 8 of 8

Thread: Copy Assignment of Reference

  1. #1
    Join Date
    Dec 2003
    Posts
    38

    Copy Assignment of Reference

    I have a function inside of which I would like to declare an object. Inside of this function I would like to add the object (after setting it's members) by reference into a container of some type or into code outside of the function in which it was declared for preservation (or persistence in different context). But as we all know when we leave a function all local variables and their memory are removed from the stack. How can I know that the declared object was actually copied into a different memory location guaranteeing preservation of the object outside of the function???

    C++ much different from JAVA!

    -Van

  2. #2
    Join Date
    Dec 2007
    Posts
    401
    containers in c++ use value semantics. so in the usual case, what is added to the container is a copy of its value_type. you could check this out by trying out this code ( in which the copy operation prints out a diagnostic)
    Code:
    #include <iostream>
    #include <list>
    #include <algorithm>
    #include <iterator>
    
    struct A
    {
      A( int v = 0 ) : value(v)  { std::cout << "A::constructor\n" ; }
      A( const A& that ) : value(that.value) { std::cout << "A::copy_constructor\n" ; }
      ~A() { std::cout << "A::destructor\n" ; }
      operator int() const { return value ; }
      // ...
      private: int value ;
    };
    
    template< typename CNTR >
    void add_to_container( CNTR& container, int v )
    {
      A local_variable(v) ;
      container.push_back( local_variable ) ;
      // adds a copy of local_variable to container
    }
    
    int main()
    {
      std::list<A> my_container ;
      for( int i=0 ; i<5 ; ++i ) add_to_container( my_container, i*i ) ;
      std::copy( my_container.begin(), my_container.end(),
                 std::ostream_iterator<int>(std::cout,"\n") ) ;
    }
    if you really want a container to hold references, you would create a container where the value_type is a pointer. for example,
    Code:
    std::list<A*> my_container_of_references ;
    in this case the container would hold a copy of an address, not the copy of the object; and you would need to manage the object lifetimes programmatically; the objects would need to have dynamic (not automatic) storage. hint: loook up the c++ keywords new and delete to see how you can create (and destroy) objects with dynamic storage duration.

  3. #3
    Join Date
    Nov 2003
    Posts
    4,118
    So long as the container object itself isn't function-local, you can copy safely any object into it. That object (notice: not a pointer) will be copied by value into the container so when the function exits, that copy will remain alive in the container.
    Danny Kalev

  4. #4
    Join Date
    Dec 2003
    Posts
    38
    Thank you to you both. The weird thing about C++ is that it seems references have dual purpose. In general, you see one being passed in from the client perspective and think that it is being modified by reference, then you do some digging and it the argument suggest that it is passed in as a const so it can't be modified, then you still need to look out to make sure whether or not there are any copy assignments which preserve the object, but somewhere else in memory. So if I'm correct you can never be completely certain as to what is happening unless you're writing your own code or you do some investigation. Perhaps, clearly one of the main sources of memory leaks...

    Thanks a Million,

    -Van

  5. #5
    Join Date
    Dec 2003
    Posts
    3,366
    it should not have anything to do with memory leaks, those are from mismatched new and delete pairs, period -- ususally it means you newed and did not delete and for the worst ones, this happens every time you enter a function.

    You almost always have access to the header file of any code you use, even if it is not your own, and you can tell what is happening from that. Modern IDE's will take you to the header at a click, or even print the parameter list as you use methods; these are helpful clues into what is happening.

    A const reference is for a class, usually, so that you can pass it into a parameter without a HUGE copy penalty yet the author is asserting that he will not modify this value. The rest of the uses are fairly normal.

    It sounds like you have inherited some odd source code. If you cannot make sense of it post the confusing bits and related sections and we can try to unravel it.
    Last edited by jonnin; 01-09-2008 at 09:44 AM.

  6. #6
    Join Date
    Nov 2003
    Posts
    4,118
    Quote Originally Posted by evac-q8r
    Thank you to you both. The weird thing about C++ is that it seems references have dual purpose. In general, you see one being passed in from the client perspective and think that it is being modified by reference, then you do some digging and it the argument suggest that it is passed in as a const so it can't be modified, then you still need to look out to make sure whether or not there are any copy assignments which preserve the object, but somewhere else in memory. So if I'm correct you can never be completely certain as to what is happening unless you're writing your own code or you do some investigation. Perhaps, clearly one of the main sources of memory leaks...

    Thanks a Million,

    -Van
    I think you're missing a crucial difference between C++ and Java: references in Java are not the same thing as C++ references. In Java, when you pass on object to a function, you're actually passing a copy of a reference. In C++ you're actually passing the reference itself (which is nothing more than the address of the object, as opposed to Java in which a reference has an extra layer of indirection). You should never be confused about memory leaks: all STL containers have value semantics. They store objects, not references nor pointers, unless you explicitly force them to store pointers. Besides, if the object has an assignment operator, it's its responsibility to copy members properly without causing any leaks. If there is a leak, it means that the code is buggy, period. In most cases, you don't even have to write an assignment operator because the automatically generated one will do the right thing, so long as the class is properly designed. Take std::string for example. Who cares how it implements copying? You just use it and the code works fine.
    Danny Kalev

  7. #7
    Join Date
    Dec 2003
    Posts
    38
    It sounds like you have inherited some odd source code. If you cannot make sense of it post the confusing bits and related sections and we can try to unravel it.
    Actually I've been programming in JAVA for years and just need to do some programming in C++. Like Danny said, the references are extremely different in each of the languages. Particularly in C++ where the reference can't be null or equivalently must be initialized where it is declared. What really made me think carefully or caused the source of my confusion was the copy assignment. I realize now that passing in a reference to the object to be copied and the passing out a reference to object copied over is for efficiency so that you're not doing 3 copies where only one is necessary.

    You're right about the memory leaks. I spoke too soon there.

    In C++ you're actually passing the reference itself (which is nothing more than the address of the object, as opposed to Java in which a reference has an extra layer of indirection).
    I don't quite see where the extra level of indirection is coming from here. I don't see how copying a reference in JAVA is any different than copying a reference or pointer in C++ unless it is an issue at a lower lying layer than the code which is inherently language specific.

    -EVAC

  8. #8
    Join Date
    Nov 2003
    Posts
    4,118
    References in Java are no memory pointers, they are integral values that are mapped under the hood to an address (which the programmer can never access), whereas in C++, references are addresses (again, under the hood), so the C++ runtime implementation doesn't have to convert references to addresses in C++. Secondly, when you assign to a reference in C++, you're actually assigning to an object -- the object bound to that reference. So in C++ a reference is really just an alias for the object itself. You can think of it as constant pointer that behaves syntactically as if it were the object bound to it.
    In Java assigning a reference has different semantics -- the reference itself is copied, IIRC. This difference between the two languages is crucial when implementing swap() or when storing elements in a container.

    References in C++ aren't used just for efficiency reasons. They have other uses such as enabling dynamic binding. When you call a function through a a reference to an object, the call is resolved dynamically, whereas calling the same function with an object name is resolved statically. There are other subtle issues with references (rvalue references, temporary biding etc.) which I'm not going to discuss here.
    Danny Kalev

Similar Threads

  1. Replies: 1
    Last Post: 10-24-2006, 01:35 AM
  2. Replies: 1
    Last Post: 04-07-2006, 06:23 PM
  3. Assignment Operator, Returning const reference
    By codemonkey32 in forum C++
    Replies: 6
    Last Post: 02-06-2006, 05:39 PM
  4. Replies: 3
    Last Post: 10-21-2005, 10:06 AM
  5. Replies: 1
    Last Post: 04-27-2005, 08:15 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center