Reputation: 1248
I am trying to get my head around the Rule of 5.
I have a class Renderable
, which defines a custom destructor, so it seemed like a good candidate for the Rule of 5. This class creates some resources in its constructor, so my first thought was that I should prevent copying:
class Renderable {
public:
Renderable(const Sprite&) {
// Allocate resources
}
~Renderable() {
// Free resources
}
// Prevent copying
Renderable(const Renderable& other) = delete;
}
I have another class, Unit
, which creates a Renderable
in the initializer list of its constructor:
class Unit {
public:
Unit(const Sprite& sprite) :
renderable(Renderable(sprite)) {}
private:
Renderable renderable;
}
I would expect this to call the regular Renderable
constructor, but instead I get the error:
Renderable::Renderable(const Renderable &)': attempting to reference a deleted function
Why is this trying to call the copy constructor?
I even tried added debug lines to the copy constructor, but nothing is printed:
Renderable(const Renderable& other) : sprite(other.sprite) {
std::cout << "copy constructor";
}
Upvotes: 0
Views: 878
Reputation: 25388
In addition to what others have said, I think you meant to write:
Unit::Unit(const Sprite& sprite) :
renderable(sprite) {}
This invokes the converting constructor Renderable(const Sprite&)
to initialise renderable
directly, no copying involved.
Upvotes: 3
Reputation: 182769
First, Renderable(sprite)
creates a Renderable
. Then you try to construct renderable
with that Renderable
. Conceptually, what could that use other than a copy constructor?
Why are you creating a Renderable
to initialize renderable
? That step is not needed and won't work because you have no copy constructor. You've specifically said that you don't want code that conceptually uses a copy constructor to work.
Upvotes: 4
Reputation: 118340
Why is this trying to call the copy constructor?
Because
renderable(Renderable(sprite)) {}
This constructs a temporary Renderable
object, and then uses it to construct the renderable
class members. That would be a
I even tried added debug lines to the copy constructor, but nothing is printed:
This is because this is one of the situations where compilers are permitted to do copy-elision. Even though the compiler optimizes away a temporary+copy construction, the constructor must still exist. Something about the class causes the default copy constructor to be deleted. There could be several reasons for that, but you did not provide sufficient information about your class in order to determine what that reason might be.
Upvotes: 1