Thread: Assigning an object variable to a constant reference

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    52

    Assigning an object variable to a constant reference

    Hi,

    Can someone please explain to me exactly what happens when line
    Rational result = left;
    is executed?

    Code:
    Rational operator+ (const Rational & left, const Rational & right)
    {
        Rational result = left;
        result += right;
        return result;
    }
    Note: in the user-defined class Rational, the assignment operator has not been redefined and no copy constructor has been defined either.

    Thanks,

    - Canadian

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Can someone please explain to me exactly what happens when line
    Rational result = left;
    is executed?
    The Rational object named result is copy constructed.

    Note: in the user-defined class Rational, the assignment operator has not been redefined and no copy constructor has been defined either.
    If the copy constructor is not explicitly declared and yet an object is copy constructed, the compiler will implicitly define the copy constructor. Likewise for the copy assignment operator.

    Incidentally, you could also have written:
    Code:
    Rational operator+ (const Rational & left, const Rational & right)
    {
        return Rational(left) += right;
    }
    or:
    Code:
    Rational operator+ (Rational left, const Rational & right)
    {
        return left += right;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> the compiler will implicitly define the copy constructor <<

    Just to add, the compiler's implicitly defined copy functions do a member-wise copy. That's good enough for most classes, which is why classes don't do their own copying.

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by laserlight View Post
    The Rational object named result is copy constructed.
    I'm sure that's what the optimizer turns it into, but I thought that line (without any optimization) would default construct a Rational object, then assign left to it?
    To copy construct it, wouldn't you need to do this:
    Code:
    Rational result( left );
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by cpjust View Post
    I'm sure that's what the optimizer turns it into, but I thought that line (without any optimization) would default construct a Rational object, then assign left to it?
    To copy construct it, wouldn't you need to do this:
    Code:
    Rational result( left );
    The example from the standard:
    Code:
    class X {
        // ...
    public:
        X(int);
        X(const X&, int = 1);
    };
    
    X a(1); // calls X(int);
    X b(a, 0); // calls X(const X&, int);
    X c = b; // calls X(const X&, int);
    Edit: A constructor marked explicit wouldn't work for the = sign, true.
    Last edited by tabstop; 11-09-2008 at 12:09 AM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Indeed, there is no copy assignment involved, despite the appearance of the "=" lexeme.

    Of course, if the copy constructor has been (explicitly) declared explicit then this syntax is not available, but Canadian0469 stated that the copy constructor was not explicitly declared.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by cpjust View Post
    I'm sure that's what the optimizer turns it into, but I thought that line (without any optimization) would default construct a Rational object, then assign left to it?
    Nope. If the = appears in the declaration, it marks an initializer expression, not an assignment operator. Thus, T t(e); and T t = e; are very closely related. Both are initializations. The first is called "direct-initialization", the second "copy-initialization". The differences between the two are very subtle, and only relevant for user-defined types with custom constructors.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    So I guess all these years I've been creating strings like this:
    Code:
    std::string str( "Hello World" );
    because I thought it was a little more efficient than:
    Code:
    std::string str = "Hello World";
    When it actually didn't make any difference?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, the former constructs str with the string literal.

    The latter, conceptually, constructs a temporary std::string with the string literal, then uses the copy constructor to construct str. But the implementation is allowed to elide the copy, and I think all compilers do this even with optimizations turned off.

    The point is, nowhere is an assignment operator involved.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by cpjust View Post
    So I guess all these years I've been creating strings like this:
    Code:
    std::string str( "Hello World" );
    because I thought it was a little more efficient than:
    Code:
    std::string str = "Hello World";
    When it actually didn't make any difference?
    But did you really think the compiler would not optimize it away anyway in Release mode?
    As CornedBee kindly points out, it hardly makes a difference. Visual Studio does not create any temporary, at the very least. It just does not work with constructors taking more than one argument.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Well even if it isn't more efficient, I guess I'll keep using construction vs assignment, since it just looks more natural for me.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Whatever fancies you
    Or maybe, whatever rocks your boat!
    I like the assignment form better, though.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If it wasn't for the silly "int i(); means I just created a function called i returning an int" issue, I'd prefer the constructor syntax.

  14. #14
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Daved View Post
    If it wasn't for the silly "int i(); means I just created a function called i returning an int" issue, I'd prefer the constructor syntax.
    That only applies to empty parentheses though, so even if that didn't declare a function, I don't see much point in adding the () there.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  15. #15
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> That only applies to empty parentheses though

    No it doesn't. I believe there are other circumstances it happens as well. Besides, adding parentheses for the int means it is initialized to 0.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Using Vectors. MinGW warning
    By Viewer in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2009, 03:15 PM
  3. Managing a reference object
    By Mario F. in forum C++ Programming
    Replies: 4
    Last Post: 11-23-2006, 07:41 PM
  4. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM