简体   繁体   中英

How should I ensure the call to the move constructor? (move semantics and rvalue reference)

I have this piece of code

#include <iostream>
#include <vector>

using namespace std;

class ArrayWrapper {
    private:
        int *_p_vals;
        int _size;

    public:
        //default constructor
        ArrayWrapper () : _p_vals( new int[ 64 ] ) , _size( 64 ) {
            cout << "default constructor called\n";
        }

        //constructor 2
        ArrayWrapper (int n) : _p_vals( new int[ n ] ) , _size( n ) {
            cout << "constructor 2 called\n";
        }

        //move constructor
        ArrayWrapper (ArrayWrapper&& other) : _p_vals(other._p_vals), _size(other._size) {  
            cout << "move constructor called\n";
            other._p_vals = nullptr;
            other._size = 0;
        }

        // copy constructor
        ArrayWrapper (const ArrayWrapper& other) : _p_vals( new int[ other._size  ] ) , _size( other._size ) {
            cout << "copy constructor called\n";
            for ( int i = 0; i < _size; ++i )
                _p_vals[i] = other._p_vals[i];
        }

        ~ArrayWrapper () {
            delete [] _p_vals;
        }

        void set_val (std::initializer_list <int> vals) {
            int i = 0;
            for (auto val : vals) {
                _p_vals[i] = val;
                i++;
            }
        }
        void print_val () const {
            for (auto i = 0; i < _size ; i++){
                cout <<_p_vals[i] << ":" ;
            }
            cout << endl;
        }
};

ArrayWrapper getArrayWrapper () {
    ArrayWrapper A(5);
    A.set_val({1,2,3,4,5});
    return A;
}

int main () {
    ArrayWrapper arr {getArrayWrapper()};
    arr.print_val();
    return 0;
}

I am trying to ensure that the move constructor is being called. But some default copy constructor is being used since the output is simply this

constructor 2 called
1:2:3:4:5:

I am using the following g++ version

g++ (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406

Should I make all the constructor calls explicit . I wonder how that would help though. Is there a way where I can force the program to call the move constructor and the copy constructor that I have written above?

Thanks to the commenters, I found out that the compiler is doing return value optimization (RVO) which prevents the calls to the constructors written above. I found a way to disable RVO. The -fno-elide-constructors switch in g++ works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM