Search code examples
c++11move

c++11 Why doesn't this move constructor work?


I've written the code posted below. I was hoping to get to move the content of a vector between instances of LargeClass. The move constructor is being used, but instead of moving I get copies only.

Why doesn't the move semantics work as expected here?

Code:

#include <iostream>
#include <vector>

class LargeClass
{
public:
    explicit LargeClass (void): numbers(20, 10) 
    {
    }
    LargeClass (const LargeClass &rhs): numbers(rhs.numbers)
    { 
        std::cout << "Using LargeClass copy constructor" << '\n';
    }
    LargeClass (const LargeClass &&rhs): numbers(std::move(rhs.numbers))
    { 
        std::cout << "Using LargeClass move constructor" << '\n';
    }

    const int* getNumbersAddress(void) const
    {
        return (numbers.data());
    }

private:
    std::vector<int> numbers;
};

int main()
{
    LargeClass l1;
    std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n';

    LargeClass l2(l1);
    std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n';
    std::cout << "l2 vector address: " << l2.getNumbersAddress() << '\n';

    LargeClass l3 = std::move(l2); 
    std::cout << "l1 vector address: " << l1.getNumbersAddress() << '\n';
    std::cout << "l2 vector address: " << l2.getNumbersAddress() << '\n';
    std::cout << "l3 vector address: " << l3.getNumbersAddress() << '\n';

    return 0;
}

Possible output:

l1 vector address: 0x18ce010
Using LargeClass copy constructor
l1 vector address: 0x18ce010
l2 vector address: 0x18ce070
Using LargeClass move constructor
l1 vector address: 0x18ce010
l2 vector address: 0x18ce070
l3 vector address: 0x18ce0d0

Solution

  • The rvalue references don't make sense in their const forms because you want to modify them (you want to "move" them ). Objects created as const in C++ are in read-only memory, from which grabbing/modifying internal resources won't be possible.

    The syntax for move constructor normally should be

    • class_name ( class_name && )

    So use :

    LargeClass ( LargeClass&& rhs )