References

tmp obj/values are unnamed, created automatically on stack when

  1. const reference initialization
    • const int& a = 1
    • const A& a = 1, only works if A has conversion constructor
  2. argument passing
  3. function return value
  4. evaluation of expression
  • 5/2

    • temp objects (not defined inside function, e.g. params) will be destructed after the line terminate, not when the function ends
  • lvalue reference is an alias to an object

  • rvalue reference is an alias to a temporary object

int main() {
    int a = 5;
    int& b = a;
    b++;
 
    int& c = 5; // ERROR
    const int& d = 5;
    d++; // ERROR
 
    int&& e = 5;
    e++;
    int&& x = a; // ERROR
}
  • lvalue ref only bind to lvalue
  • rvalue ref only bind to rvalue
  • except const lvalue ref

Move

  • Return by value will be done by move instead of copy
// Example p.23
 
// Move constructor
// Note that str(w.str) is copying the pointer
Word(Word&& w) : freq(w.freq), str(w.str) {
    w.freq = 0;
    w.str = nullptr;
    cout << "move: ";
    print();
}
 
// Move assignment
Word& operator=(Word&& w) {
    if (this != &w) {
        delete [] str;
        freq = w.freq; str = w.str;
        w.freq = 0; w.str = nullptr;
        cout << "move assignment: "; print();
    }
    return *this;
}
// Pass by rvalue reference &&, construct by moving
// We need std::move here because after we initalized the rvalue reference, it is now actually a lvalue (a and b)
Word_Pair(Word&& a, Word&& b) : w1(std::move(a)), w2(std::move(b)) {
    cout << "\n-- Another move with inputs --\n"; a.print(); b.print(); 
}
  • when using std::move, no tmp is created, so no destructor