I want to write a class that uses the PIMPL idiom but makes the following possible:
int main() {
MyClass myclass {12};
std::string val = myclass.get_value();
std::cout << val << "\n";
MyClass copy = myclass;
val = copy.get_value();
return 0;
}
That is, provide copy functionality while using PIMPL. Using std::unique_ptr
to implement PIMPL leads to the expected compile error:
error C2280: 'MyClass::MyClass(const MyClass &)': attempting to reference a deleted function
This is my attempt:
class.hpp
#pragma once
#include <string>
#include "copyable_unique_ptr.hpp"
class MyClass {
private:
struct MyClassPrivate;
copyable_unique_ptr<MyClassPrivate> _impl;
public:
MyClass(int value);
~MyClass();
std::string get_value();
};
class.cpp
#include "class.hpp"
#include <string>
struct MyClass::MyClassPrivate {
int value;
};
MyClass::MyClass(int value)
: _impl(std::make_unique<MyClassPrivate>()) {
_impl->value = value;
}
MyClass::~MyClass() = default;
std::string MyClass::get_value() {
return std::to_string(_impl->value);
}
copyable_unique_ptr.hpp
#pragma once
#include <memory>
template <typename T>
class copyable_unique_ptr {
private:
std::unique_ptr<T> _ptr;
public:
copyable_unique_ptr(std::unique_ptr<T> &&ptr)
: _ptr(std::move(ptr)) {}
~copyable_unique_ptr() = default;
copyable_unique_ptr(const copyable_unique_ptr<T> &other) {
_ptr = std::make_unique<T>(*other._ptr);
}
copyable_unique_ptr(const copyable_unique_ptr<T> &&other) {
_ptr = std::move(other._ptr);
}
copyable_unique_ptr &operator=(const copyable_unique_ptr<T> &other) {
_ptr = std::make_unique<T>(*other._ptr);
}
copyable_unique_ptr &operator=(const copyable_unique_ptr<T> &&other) {
_ptr = std::move(other._ptr);
}
T *operator->() {
return _ptr.get();
}
};
which leads to the following error: warning C4150: deletion of pointer to incomplete type 'MyClass::MyClassPrivate'; no destructor called
I also had this error when first trying to use unique_ptr, and the solution was to move the destructor into class.cpp: MyClass::~MyClass() = default;
.
I don't really know how to solve this problem while using the approach with copyable_unique_ptr
.
I saw this question on SO. They are trying to do the same as me, but the last comment to the answer suggests that they are having exactly the same problem.
Aucun commentaire:
Enregistrer un commentaire