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