3

I have been reading the book "The C++ programing language 4th edition" by Bjarne Stroustrup (The creator of c++) and have been learning about move constructors and move assignments.

In the book for the class vector (see 1 for header below) he shows how to implement the move constructor (see 2 below) and says the move assignment is implemented in a similar manner but doesn't show how. I have implemented the move assignment myself (see 3 below) and everything seems to be working fine, however, I am not sure I have implemented it correctly.

I am not getting any errors and have looked at many examples but I cannot confirm its correct for my specific class. Can someone experienced with c++ please look at my code and comment if it is correct?

EDIT: Also please see 4 for constructors and destructor.

Thank you for your time.

P.S: Any helpful hints or modifications are welcome

1) Class Header File:

#ifndef VECTOR_H
#define VECTOR_H

#include <cstdlib>
#include <iostream>
#include <stdexcept>

using namespace std;

template<typename T>
class Vector {

public:
    // constructors
    Vector(int s);
    Vector(std::initializer_list<T>);

    // destructor
    ~Vector();

    // copy constructor and copy assignment
    Vector(Vector&);
    Vector<T>& operator=(Vector&);

    // move constructor and move assignment
    Vector(Vector&&);
    Vector<T>& operator=(Vector&&);

    // operators
    T& operator[](int);
    const T& operator[](int) const; // the second const means that this function cannot change the state of the class
                                    // we define operator[] the second time for vectors containing constant members;
    // accessors
    int getSize();


private:
    int size;
    T* elements;

};

#endif /* VECTOR_H */

2) Move constructor (implemented in the same way as book):

// move constructor 
template<typename T>
Vector<T>::Vector(Vector&& moveme) : size{moveme.size}, elements{moveme.elements}
{
    moveme.elements = nullptr;
    moveme.size = 0;
}

3) Move assignment (not sure if correct):

// move assignment
template<typename T>
Vector<T>& Vector<T>::operator=(Vector&& moveme) 
{
    delete[] elements; // delete old values
    elements = moveme.elements;
    size = moveme.size;
    moveme.elements = nullptr;
    moveme.size = 0;
    return *this;
}

4) Constructors and destructor:

#include <array>

#include "Vector.h"

// constructors
template<typename T>
Vector<T>::Vector(int s) {    
    if(s<0) throw length_error{"Vector::Vector(int s)"};
    // TODO: use Negative_size{} after learning how to write custom exceptions
    this->size = s;
    this->elements = new T[s];
}

template<typename T>
Vector<T>::Vector(std::initializer_list<T> list) : size(list.size()), 
        elements(new T[list.size()]) 
{
    copy(list.begin(), list.end(), elements);
}

// destructor
template<typename T>
Vector<T>::~Vector()
{
    delete[] this->elements;
}
19
  • 1
    The move assignment seems reasonable, except that putting templates in a cpp file makes them usable in that cpp file only. See Why can templates only be implemented in the header file? Commented Sep 23, 2017 at 13:33
  • 1
    @hammeramr Putting template code in a *.cpp file is confusing to people who might expect it to be compilable, and also to some IDEs or build systems which might automatically try to actually compile it, which is pointless. Commented Sep 23, 2017 at 13:44
  • 1
    @hammeramr std::move != move semantics. You have move semantics, where rvalues can be moved (using the move constructor) instead of copied. std::move is just a facility to enable move semantics (like using the move constructor) for types that are not rvalues. Commented Sep 23, 2017 at 15:22
  • 1
    @hammeramr The one with std::move. Just like using a const& for for example int as a parameter to a function. It doesn't matter from a performance standpoint because int is so small, it can be passed around in registers. Same thing for moving it. Use the one you like better - I don't use it, because it's less to type :P Commented Sep 23, 2017 at 15:32
  • 1
    @hammeramr No, what I meant with child_vector is if you had a member called that in the class. But you don't, so forget that. Also, is there really no return-value-optimization, if you don't have overloaded move ctors/assignments? Commented Sep 23, 2017 at 17:23

1 Answer 1

3

Since this question was answered in the comments I thought I'd follow the advice from the meta: Question with no answers, but issue solved in the comments (or extended in chat) and write a short Community Wiki to close and answer the question.

I will also add useful additional info and tips from other users who joined the discussion in the comments.

Bo Presson answering and providing additional info on template placement:

The move assignment seems reasonable, except that putting templates in a cpp file makes them usable in that cpp file only. See Why can templates only be implemented in the header file?

Rakete1111 clarifying a misconception I had regarding move semantics:

std::move != move semantics. You have move semantics, where rvalues can be moved (using the move constructor) instead of copied. std::move is just a facility to enable move semantics (like using the move constructor) for types that are not rvalues.

kim366 bringing up return optimization question with Jive Dadson and I answering:

... Also, is there really no return-value-optimization, if you don't have overloaded move ctors/assignments ? -kim366

It seems so, in the example (see function below) he says that z = x + y + z will copy the return result twice "If a Vector is large, say, 10,000 doubles, that could be embarrassing." But "Given that definition, the compiler will choose the move constructor to implement the transfer of the return value..." He invented c++ so ill just take his word for it :). Vector operator+(const Vector& a, const Vector& b) { if (a.size()!=b.size()) throw Vector_size_mismatch{}; Vector res(a.size()); for (int i=0; i!=a.size(); ++i) res[i]=a[i]+b[i]; return res; } - hammeramr

(Example was from the book: "The C++ programing language 4th edition" by Bjarne Stroustrup)

See also What is the copy-and-swap idiom? -Jive Dadson

Hope people find this useful and thanks for those who participated.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.