Should std::unique_ptr<>
be used as an easier way to implement move semantics?
For a class like
class Foo
{
int* m_pInts;
// other members ...
public:
Foo(size_t num) {
m_pInts = new int[num];
}
~Foo() {
delete[] m_pInts;
}
// no copy, but move
Foo(const Foo&) = delete;
Foo& operator=(const Foo&) = delete;
Foo(Foo&& other) {
*this = std::move(other);
}
Foo& operator=(Foo&& other) {
m_pInts = other.m_pInts;
other.m_pInts = nullptr;
return *this;
}
};
Implementing move becomes more difficult as data members are added. However, the moveable data can be placed in a separate struct
, an instance of which is managed by std::unique_ptr<>
. This allows =default
to be used for move:
class Bar
{
struct Data
{
int* m_pInts;
// other members ...
};
std::unique_ptr<Data> m_pData = std::make_unique<Data>();
public:
Bar(size_t num) {
m_pData->m_pInts = new int[num];
}
~Bar() {
if (m_pData) // might have been std::move()d to another instance
delete[] m_pData->m_pInts;
}
// no copy, but move
Bar(const Bar&) = delete;
Bar& operator=(const Bar&) = delete;
Bar(Bar&& other) = default;
Bar& operator=(Bar&& other) = default;
};
Other than the memory for the unique_ptr<>
instance always being on the heap, what other problems exist with an implementation like this?
Aucun commentaire:
Enregistrer un commentaire