constructors and assignment operators
Could someone check if the constructors and assignment operators are in a right manner?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
#include <iostream>
#include <stdexcept>
using std::cout;
template<typename T>
struct X
{
T * data;
int size = 0;
int reserved = 8;
X() { data = new T[reserved]; cout << this << " constructor\n"; }
X( const X & x ) :size(x.size),reserved(x.reserved) {
cout << this << " copy constructor\n";
data = new T[reserved];
for( int i = 0; i < size; ++i ) data[i] = x.data[i];
}
X( X && x ) :data(x.data),size(x.size),reserved(x.reserved) {
cout << this << " move constructor\n";
x.data = nullptr; x.size = 0; x.reserved = 0;
}
~X() { delete[] data; cout << this << " destructor\n"; }
X& operator=( const X& other) {
cout << "copy assignment\n";
if( this == &other) return *this;
if( reserved < other.size) {
delete[] data;
data = new T[other.size];
reserved = other.size;
}
size = other.size;
for(int i = 0; i < size; ++i) data[i] = other.data[i];
return *this;
}
X& operator=( X&& other) {
cout << "move assignment\n";
data = other.data; reserved = other.reserved; size = other.size;
other.data = nullptr; other.reserved = 0; other.size = 0;
return *this;
}
T& at(int i) {
if(i < 0 || i >= size) throw std::out_of_range("out of range");
return data[i];
}
const T& at(int i) const {
if( i < 0 || i >= size) throw std::out_of_range("out of range");
return data[i];
}
void push_back( T t ) {
if( size == reserved ) {
T * tmp = data;
data = new T[ 2*size ];
for( int i = 0; i < size; ++i) data[i] = tmp[i];
delete[] tmp;
}
data[size++] = t;
}
};
X<char> f() {
X<char> x;
x.push_back('f');
cout << "doing something\n";
return x;
}
int main()
{
X<char> x1 = f();
cout << x1.at(0) << '\n';
x1.push_back('a');
x1.at(0) = 'b';
cout << x1.at(0) << '\n';
X x2 = x1;
x1 = x2;
x2 = x1;
X<char> x3;
x3 = X<char>{};
}
|
Last edited on
In function
1 2 3 4 5 6 7 8 9
|
void push_back( T t ) {
if( size == reserved ) {
T * tmp = data;
data = new T[ 2*size ];
for( int i = 0; i < size; ++i) data[i] = tmp[i];
delete[] tmp;
}
data[size++] = t;
}
|
you miss assign a new value to
reserved
In assignment operator the following instructions ( in order to copy the exact state of object )
1 2
|
data = new T[other.size];
reserved = other.size;
|
should be change to ( assuming that always
reserved >
size )
1 2
|
data = new T[other.reserved];
reserved = other.reserved;
|
Last edited on
1 2 3 4 5 6
|
X& operator=(X&& other) {
cout << "move assignment\n";
data = other.data; reserved = other.reserved; size = other.size;
other.data = nullptr; other.reserved = 0; other.size = 0;
return *this;
}
|
You have a memory leak as you are not deleting the memory originally used. You should use
1 2 3 4 5 6 7
|
X& operator=(X&& other) {
cout << "move assignment\n";
swap(data, other.data);
swap(reserved, other.reserved):
swap(size, other.size);
return *this;
}
|
when the temp (rvalue) object is now destroyed, it will free the memory originally used.
Topic archived. No new replies allowed.