Można też rozważyć użycie klas interfejsowych (w C++ tych ze wszystkimi metodami czysto wirtualnymi) a całą implementację wrzucić do pliku .cpp do klasy dziedziczącej po tej w pliku nagłówkowym. I dodac jakąś statyczną funkcję fabrykującą.
Coś w stylu:
//foo.hpp
#include <memory>
struct Foo {
typedef std::auto_ptr<Foo> Ptr_t;
~virtual Foo() = 0;
virtual void set(int x) = 0;
virtual void print() const = 0;
static Ptr_t create(); // statyczna metoda fabrykująca
};
// foo.cpp
include "foo.hpp"
#include <iostream>
using std::cout;
Foo::~Foo() {}
struct Foo_impl : Foo {
Foo_impl() : m_x(0) {}
virtual void set(int x) { m_x = x; }
virtual void print() const { cout << m_x << '\n'; }
int m_x;
};
void Foo::create()
{
return Ptr_t(new Foo_impl());
}
//main.cpp
#include "foo.hpp"
int main()
{
Foo::Ptr_t ptr(Foo::create());
ptr->print();
ptr->set(42);
ptr->print();
}
Fakt, że wtedy mamy do czynienia z jakimś tam wskaźnikiem a nie obiektem.