Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The key here (as touched upon by a previous poster) but worth emphasizing is that expressions in C++ can be categorized as being either rvalues or lvalues. </p> <p>Their is much detail behind those categories, but a useful heuristic to guide your intuition is: if you can take the address of an expression (such as a variable) it is an lvalue (there is much more to the story here, but this is a good place to start).</p> <p>If it is truly not an lvalue, it is an rvalue - and a useful heuristic for rvalues is that they represent "hidden" temporary objects that the compiler instantiates to make your code work. These objects are created and destroyed by the compiler behind the scenes.</p> <p>Why is this relevant here?</p> <p>Well, in C++98/03 (which is what i presume you are using), remember the following two rules:</p> <p>1) Only lvalue expressions can bind to non-const references (ignoring casts) 2) rvalue expressions can bind to only const references (ignoring casts)</p> <p>An example will help here:</p> <pre><code>// Consider the function foo below - it returns an int - // whenever this function is called, the compiler has // to behave as if a temporary int object with the value 5 is returned. // The use of 'foo()' is an expression that is an rvalue - try typing &amp;foo() - // [Note: if foo was declared as int&amp; foo(), the story gets complicated, so // i'll leave that for another post if someone asks] int foo() { return 5; } void bind_r(int&amp; r) { return; } void bind_cr(const int&amp; cr) { return; } int main() { int i = 10; // ok int&amp; ri = i; // ok binding lvalue to non-const reference, see rule #1 int&amp; ri2 = foo(); // Not ok, binding a temporary (rvalue) to a non-const reference // The temporary int is created &amp; destroyed by compiler here const int&amp; cri = foo(); // ok - see rule #2, temporary int is NOT destroyed here //Similarly bind_r(i); // ok - rule #1 bind_r(foo()); // NOT ok - rule #2 bind_cr(foo()); // ok - rule #2 // Since the rules above keep you out of trouble, but do not exhaust all possibilities // know that the following is well-formed too: const int&amp; cri2 = i; bind_cr(i); bind_cr(cri); bind_cr(cri2); } </code></pre> <p>When you bind an rvalue to a const reference, you basically extend the temporary object's life-time to the life-time (in this case scope) of the reference (and the compiler can not just destroy it at the end of that expression) - so you end up with a reference to a valid object.</p> <p>I hope this helps in understanding why you have to declare your assignment operator as accepting a const reference and not just a non-const reference, as one of the other posters rightly recommended.</p> <p>p.s. There are some other issues with your code (such as why you are destroying and creating the memory that your object exclusively points to upon each assignment, and the lack of a copy constructor and destructor), and if no one has addressed them by the time this post appears, i will :)</p> <p>p.s. It may also be worth knowing that C++0x adds something known as rvalue references (non-const) that preferentially bind to rvalues and provide for extremely powerful optimization opportunities for the programmer (without having to rely on the optimization capabilities of the compiler) - they also help solve the problem of creating the perfect forwarding function in C++ - but now we're digressing ;)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload