(C++) PimplExample1
July 25, 2018 · View on GitHub
pimpl example 2: Lizard implementation in multiple files using std::shared_ptr is a pimpl example.
Most lizards remain having the same gender for all their live. Therefore, it is a good idea to make a lizard's gender a const member variable. Problem is, that this makes a lizard class uncopyable. In this example I solve this by making a Lizard contain an opaque pointer to LizardImpl, where a LizardImpl does have a constant gender. Because I want to be able to do a shallow copy on Lizards, I use a std::shared_ptr. Also note that the code is very similar to a Strategy design pattern.
CppPimpl.pro
TEMPLATE = app
CONFIG += console c++17
CONFIG -= app_bundle
CONFIG -= qt
QMAKE_CXXFLAGS += -std=c++17
SOURCES += \
CppPimplMain.cpp \
CppPimplLizard.cpp
HEADERS += \
CppPimplLizard.h
CppPimplLizard.h
#ifndef CPP_PIMPL_LIZARD_H
#define CPP_PIMPL_LIZARD_H
enum class Gender { male, female };
#include <memory>
class Lizard
{
public:
Lizard(const Gender gender);
~Lizard();
Gender GetGender() const noexcept;
private:
struct LizardImpl;
std::shared_ptr<LizardImpl> mPimpl;
};
#endif // CPP_PIMPL_LIZARD_H
CppPimplLizard.cpp
#include "CppPimplLizard.h"
struct Lizard::LizardImpl
{
LizardImpl(const Gender gender);
const Gender mGender;
};
Lizard::Lizard(const Gender gender)
: mPimpl(std::make_shared<LizardImpl>(gender))
{
}
Lizard::~Lizard()
{
//Need destructor definition in implementation file
}
Gender Lizard::GetGender() const noexcept
{
return mPimpl->mGender;
}
Lizard::LizardImpl::LizardImpl(const Gender gender) : mGender(gender)
{
}
main.cpp
#include <vector>
#include "CppPimplLizard.h"
int main()
{
std::vector<Lizard> lizards = {
Lizard(Gender::male),
Lizard(Gender::female)
};
std::swap(lizards[0], lizards[1]);
}