I grabbed the following code from Ten C++11 Features Every C++ Developer Should Use. I want to see the output with / without move constructor
and move assignment operator
. The original code compiles well. But if I comment out implementation of the two methods, it fails to compile with error:
move-1.cpp: In instantiation of ‘Buffer<T>& Buffer<T>::operator=(const Buffer<T>&) [with T = int]’:
move-1.cpp:90:6: required from here
move-1.cpp:40:17: error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<int [], std::default_delete<int []> >’ and ‘int*’)
_buffer = _size > 0 ? new T[_size] : nullptr;
Compiler: gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4)
Here is the code:
#include <cassert>
#include <iostream>
#include <memory>
#include <string>
template <typename T> class Buffer {
std::string _name;
size_t _size;
std::unique_ptr<T[]> _buffer;
public:
// default constructor
Buffer() : _size(16), _buffer(new T[16]) {
std::cout << "default constructor\n";
}
// constructor
Buffer(const std::string &name, size_t size)
: _name(name), _size(size), _buffer(new T[size]) {
std::cout << "param constructor\n";
}
// copy constructor
Buffer(const Buffer ©)
: _name(copy._name), _size(copy._size), _buffer(new T[copy._size]) {
T *source = copy._buffer.get();
T *dest = _buffer.get();
std::copy(source, source + copy._size, dest);
std::cout << "copy constructor\n";
}
// copy assignment operator
Buffer &operator=(const Buffer ©) {
if (this != ©) {
_name = copy._name;
if (_size != copy._size) {
_buffer = nullptr;
_size = copy._size;
_buffer = _size > 0 ? new T[_size] : nullptr;
}
T *source = copy._buffer.get();
T *dest = _buffer.get();
std::copy(source, source + copy._size, dest);
std::cout << "copy assignment\n";
}
return *this;
}
// move constructor
Buffer(Buffer &&temp)
: _name(std::move(temp._name)), _size(temp._size),
_buffer(std::move(temp._buffer)) {
temp._buffer = nullptr;
temp._size = 0;
std::cout << "move constructor\n";
}
// move assignment operator
Buffer &operator=(Buffer &&temp) {
assert(this != &temp); // assert if this is not a temporary
_buffer = nullptr;
_size = temp._size;
_buffer = std::move(temp._buffer);
_name = std::move(temp._name);
temp._buffer = nullptr;
temp._size = 0;
std::cout << "move assignment\n";
return *this;
}
};
template <typename T> Buffer<T> getBuffer(const std::string &name) {
Buffer<T> b(name, 128);
return b;
}
int main() {
Buffer<int> b1;
Buffer<int> b2("buf2", 64);
Buffer<int> b3 = b2;
Buffer<int> b4 = getBuffer<int>("buf4");
b1 = getBuffer<int>("buf5");
return 0;
}
Aucun commentaire:
Enregistrer un commentaire