lundi 17 août 2020

(C++) PImpl and singleton alternative implementation

Let's suppose we have a simple class which uses a heavy dependency in its implementation:

#include "heavy_third_party_header.h"

class Feature
{
public:
    void Foo(int x);
    void Bar(int y);

private:
    third::party::member member_;
}

We could abstract the client out of the dependency with PImpl in a way like this:

// Feature.h
#include <memory>

class Feature
{
public:
    Feature();

    void Foo(int x);
    void Bar(int y);

private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};

// Feature.cpp
#include "Feature.h"
#include "heavy_third_party_dep.h"

class Feature::Impl
{
public:
    void Foo(int x) { }
    void Bar(int y) { }

private:
    third::party::member member_;
};

Feature::Feature(): impl_(std::make_unique<Feature::Impl>()) {}

void Feature::Foo(int x)
{
    impl_->Foo(x);
}

void Feature::Bar(int y)
{
    impl_->Bar(y);
}

As you see there is a noticeable overhead: we have to define an extra class and a set of proxy methods. I used to abstract out of the implementation details in an alternative way:

// Feature.h
#include <memory>

class IFeature
{
public:
    virtual void Foo() = 0;
    virtual void Bar() = 0;

    virtual ~IFeature() = default;
};

std::unique_ptr<IFeature> MakeFeature();

// Feature.cpp
#include "Feature.h"

#include "heavy_third_party_dep.h"

class Feature: public IFeature
{
public:
    void Foo() override {}
    void Bar() override {}

private:
    third::party::member member_;
};

std::unique_ptr<IFeature> MakeFeature()
{
    return std::make_unique<Feature>();
}

I also similarly implement Singleton: I define an interface of a class and a method to make an instance in the header and define a class with actual implementation in cpp file. How do you feel about such code? Would you recommend to use it instead of the reference implementation?

Aucun commentaire:

Enregistrer un commentaire