I have a class with one strong pointer and a lot of object members. Writing copy and move constructors for an object like this involves a lot of tedious copy/pasting, however...
Is there any way to shorten this, without giving up my beautiful naked pointer? Like if I could perform the default generated move operation, with just one extra instruction to nullify the naked pointer afterwards?
class Example {
public:
Example()
: m_multiplexDevice(getDevice(B737M_mpDevice, true))
{
engageDevice(m_multiplexDevice);
}
Example(Example && other)
: m_multiplexDevice (other.m_multiplexDevice )
, m_pilotStack (std::move(other.m_pilotStack ))
, m_pasStack (std::move(other.m_pasStack ))
, m_pitchAttackLimits (std::move(other.m_pitchAttackLimits))
, m_yawToPitchBalance (std::move(other.m_yawToPitchBalance))
, m_engineBalance (std::move(other.m_engineBalance ))
{
other.m_multiplexDevice = NULL;
}
Example & operator=(Example && other) {
if (this != &other) {
// ignore that this is incorrect (not properly destroying in assignment),
// working with client code that kinda sucks
m_multiplexDevice = other.m_multiplexDevice;
m_pilotStack = std::move(other.m_pilotStack );
m_pasStack = std::move(other.m_pasStack );
m_pitchAttackLimits = std::move(other.m_yawToPitchBalance );
m_yawToPitchBalance = std::move(other.m_yawToPitchBalance );
m_engineBalance = std::move(other.m_engineBalance );
m_multiplexDevice = NULL;
}
return *this;
}
Example(const Example & other) =delete;
Example & operator=(const Example & other) =delete;
~Example() {
if (m_multiplexDevice)
disengageDevice(m_multiplexDevice);
delete m_multiplexDevice;
}
private:
char STRONG * m_multiplexDevice;
std::vector<uint32> m_pilotStack;
std::vector<uint32> m_pasStack;
std::vector<uint32> m_pitchAttackLimits;
std::vector<uint32> m_yawToPitchBalance;
std::vector<uint32> m_engineBalance;
// ... etc
};
CodePudding user response:
Use a unique_ptr
with a custom deleter.
#include <memory>
#include <vector>
#include <cstdint>
#define STRONG /* ??? */
void disengageDevice(char STRONG*);
#define B737M_mpDevice 1
char STRONG *getDevice(int, ...);
void engageDevice(char STRONG *);
class Example {
public:
Example()
: m_multiplexDevice(
getDevice(B737M_mpDevice, true),
deconstruct_m_multiplexDevice)
{
engageDevice(m_multiplexDevice.get());
}
static void deconstruct_m_multiplexDevice(char STRONG *p) {
if (p) {
disengageDevice(p);
delete p;
}
}
private:
std::unique_ptr<
char STRONG,
decltype(&deconstruct_m_multiplexDevice)
> m_multiplexDevice;
std::vector<uint32_t> m_pilotStack;
std::vector<uint32_t> m_pasStack;
std::vector<uint32_t> m_pitchAttackLimits;
std::vector<uint32_t> m_yawToPitchBalance;
std::vector<uint32_t> m_engineBalance;
// ... etc
};