Reputation: 1228
so i have a class with deleted copy ctor/assignment, no default ctor, and has move ctor/assignment:
class A {
int data_ = 0;
public:
A(const A& other) = delete;
A& operator=(const A& other) = delete;
A(int data) : data_(data) {}
~A() {}
A(A&& other) { *this = std::move(other); }
A& operator=(A&& other) {
if (this != &other) {
data_ = other.data_;
other.data_ = 0;
}
return *this;
}
};
and i have a class B (also no default ctor) that contains A:
class B {
A a;
public:
B(const B& other) = delete;
B& operator=(const B& other) = delete;
B(int data) : a(data) {}
~B() {}
B(B&& other) { *this = std::move(other); }
B& operator=(B&& other) {
if (this != &other) {
a = std::move(other.a);
}
return *this;
}
};
now the problem is the B move ctor wont compile, because he says theres no default constructor for A, and this is really annoying, i dont want him to create a new A instance when i call the move ctor on B, i want it to move it!
so theres 2 things i could do:
B(B&& other) : a(std::move(other.a)) { *this = std::move(other); }
this wont work, because in the move assignment he will try to move A again.. also if "this == &other == true" he will have moved A from himself making A garbage now..
another way:
make a default private A ctor. make B friend of A. but that sounds so hacky and ugly.. what is the best way to deal with this situation? i really want to avoid having to make a default constructor for A.
thanks in advance.
Upvotes: 1
Views: 370
Reputation: 763
The solution would be to do this:
class A {
int data_ = 0;
public:
A(const A& other) = delete;
A& operator=(const A& other) = delete;
A(int data) : data_(data) {}
~A() {}
A(A&& other) : data_(other.data_) { other.data_ = 0; }
A& operator=(A&& other) {
if (this != &other) {
data_ = other.data_;
other.data_ = 0;
}
return *this;
}
};
class B {
A a;
public:
B(const B& other) = delete;
B& operator=(const B& other) = delete;
B(int data) : a(data) {}
~B() {}
B(B&& other) : a(std::move(a)) { }
B& operator=(B&& other) {
if (this != &other) {
a = std::move(other.a);
}
return *this;
}
};
Although, since A only contains an int in it, it would not result in better performance than a copy...
Upvotes: 1
Reputation: 8400
Since you have an Object of A
declared in your class B
, you need to create it when you construct B
. A normal Object in C++ can't have no value and it could not be created (cause there is no default constructor).
To fix your problem, make a pointer to a
that can have the value 0
, so it needn't to be created in your constructor. Change this line:
A a;
into this:
private:
A *a = 0;
Upvotes: 0