I've seen many questions and answers regarding the copy-and-swap idiom (when combined with the pimpl idiom). I recently implemented a class using both, and ended up with some questions:
1 In case of a pimpled class, do I (still) need a non-member friend swap
function (as described in this question)? As the question is already 10 years old, are there any changes regarding this?
2 In case of a pimpl (based on a unique ptr), wouldn't the standard std::swap
work just fine? (In which case I wouldn't need a custom swap)
3 I have all my members in a pimpl struct. In case everything is copyable, coulnd't I just use the default copy constructor?
// trial.h
class Trial
{
public:
Trial(ID a_ID = UNKNOWN_ID);
Trial(const Trial& rhs);
Trial(Trial&& rhs) noexcept;
~Trial();
Trial& operator=(Trial rhs);
void swap(Trial& rhs);
inline ID GetID() const;
private:
struct TrialImpl;
std::unique_ptr<TrialImpl> m_Impl;
};
// trial.cpp
struct Trial::TrialImpl
{
TrialImpl(ID a_ID) :
m_ID(a_ID){}
TrialImpl(const TrialImpl& rhs)
{
// make a deep copy (perhaps use default copy constructor)
m_ID = rhs.m_ID;
m_Frames = rhs.m_Frames;
}
ID m_ID;
std::vector<Frame> m_Frames;
};
Trial::Trial(ID a_ID) :
m_Impl(std::make_unique<TrialImpl>(a_ID))
{
}
Trial::Trial(const Trial& rhs) :
m_Impl(std::make_unique<TrialImpl>(*rhs.m_Impl))
{
}
Trial::Trial(Trial&&) noexcept = default;
Trial::~Trial() = default;
Trial& Trial::operator=(Trial rhs)
{
swap(rhs);
return *this;
}
void Trial::swap(Trial& rhs)
{
// we can just let std::swap swap the unique pointers
std::swap(m_Impl, rhs.m_Impl);
}
ID Trial::GetID() const
{
return m_Impl->m_ID;
}
Aucun commentaire:
Enregistrer un commentaire