Below is the simplified version of a class that I am trying to design
class Class {
public:
Class(std::unique_ptr<int>&& ptr): ptr_(std::move(ptr)) {}
private:
// works only if I change to std::shared_ptr or remove const qualifier
const std::unique_ptr<int> ptr_;
};
int main() {
std::unique_ptr<int> ptr = std::make_unique<int>(1);
Class c(std::move(ptr)); // Compiles
// I need to construct a new instance d, but c is not needed anymore,
// anything c owns can be nullified.
Class d(std::move(c)); // Does not compile
return 0;
}
I can not construct an instance d
from the instance c
due to the following error message:
Copy constructor of 'Class' is implicitly deleted because field 'ptr_' has a deleted copy constructor
However, if I change the ptr_
member to be of type const std::shared_ptr<int>
, then everything works.
Is there a way to have a single constructor for the Class
, which would support:
- Constructing the class instance directly providing the arguments it needs
- Constructing the class instance from another class instance, possibly destroying another instance in the process (i.e. c(std::move(d));
- Allowing the class to have a member of type
const unique_ptr
?
EDIT: constructing an instance d
using std::move(c)
also doesn't work:
class.cc:17:23: error: use of deleted function ‘Class::Class(Class&&)’ 17 | Class d(std::move(c)); | ^ class.cc:5:7: note: ‘Class::Class(Class&&)’ is implicitly deleted because the default definition would be ill-formed:
So far two solutions work for me, neither are perfect from readability point of view:
Remove
const
qualifier:std::unique_ptr<int> ptr_
;The problem is that this reads as: "ptr_ member might be modified when calling public methods"
Change to shared pointer:
const std::shared_ptr<int> ptr_
;The problem is that this reads as: "we have multiple pointers pointing to the same data"
Any way to improve the design which wouldn't have the problems outlined in (1) and (2)?