传统的PImpl Idiom是这样的:
#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
但是,for fun, I tried使用具有私有继承的合成:
[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;
}
我喜欢这个替代版本的工作方式,但是我很好奇它是否比传统版本有任何重大缺点?
编辑:DyP已经提供了another version,这甚至更“漂亮”。
答案 0 :(得分:0)
据我所知,使用pimpl习语的原因之一是隐藏界面用户的功能细节。在具有私有继承示例的组合中,我相信您正在向用户公开您的实现细节。