替代PImpl成语 - 优势与劣势?

时间:2013-10-01 20:21:33

标签: c++ c++11 composition pimpl-idiom object-composition

传统的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;
}

http://ideone.com/WcxJu2

我喜欢这个替代版本的工作方式,但是我很好奇它是否比传统版本有任何重大缺点?

编辑:DyP已经提供了another version,这甚至更“漂亮”。

1 个答案:

答案 0 :(得分:0)

据我所知,使用pimpl习语的原因之一是隐藏界面用户的功能细节。在具有私有继承示例的组合中,我相信您正在向用户公开您的实现细节。