Альтернативный язык идиомы — преимущества против недостатков?

Традиционная идиома PImpl выглядит следующим образом:

#include <memory>

struct Blah
{
//public interface declarations

private:
struct Impl;
std::unique_ptr<Impl> impl;
};

//in source implementation file:

struct Blah::Impl
{
//private data
};
//public interface definitions

Тем не мение, ради интереса я попробовал вместо этого использовать композицию с частным наследованием:

[Test.h]
#include <type_traits>
#include <memory>

template<typename Derived>
struct PImplMagic
{
PImplMagic()
{
static_assert(std::is_base_of<PImplMagic, Derived>::value,
"Template parameter must be deriving class");
}
//protected: //has to be public, unfortunately
struct Impl;
};

struct Test : private PImplMagic<Test>,
private std::unique_ptr<PImplMagic<Test>::Impl>
{
Test();
~Test();
void f();
};
[первый переводческий блок]
#include "Test.h"int main()
{
Test t;
t.f();
}
[второй переводческий блок]
#include <iostream>
#include <memory>

#include "Test.h"
template<>
struct PImplMagic<Test>::Impl
{
Impl()
{
std::cout << "It works!" << std::endl;
}
int x = 7;
};

Test::Test()
: std::unique_ptr<Impl>(new Impl)
{
}

Test::~Test() // required for `std::unique_ptr`'s dtor
{}

void Test::f()
{
std::cout << (*this)->x << std::endl;
}

http://ideone.com/WcxJu2

Мне нравится, как работает эта альтернативная версия, однако мне интересно, есть ли у нее серьезные недостатки по сравнению с традиционной версией?

РЕДАКТИРОВАТЬ: DyP любезно предоставил еще другая версия, что еще красивее.

5

Решение

Из того, что я понимаю, одна из причин использования идиомы pimpl заключается в том, чтобы скрыть детали функциональности от пользователя вашего интерфейса. Я полагаю, что в вашей композиции с частным наследованием вы раскрываете детали своей реализации пользователю.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]