很抱歉这个漫长而令人困惑的标题.
我有这样的类头文件
#pragma once
#include <thread>
#include <boost/asio.hpp>
#include <another3rdpartylib/doodads.h>
class A {
public:
A();
Method1();
Method2();
private:
std::thread thread;
boost::asio::socket socket;
another3dpartylib::doodad gizmo;
}
Run Code Online (Sandbox Code Playgroud)
现在,班级的用户不会也不应该关心私人部分.如何在不拖动的情况下允许用户包含该类<thread>,<boost/asio.hpp>并且<another3rdpartylib/doodads.h>?
从技术上讲,用户唯一应该关心的是sizeof(A).我错了吗?
C++中分割接口和类实现的常用方法是使用指针实现(PIMPL)成语.
PIMPL惯用法通过将引用/指针存储到负责执行操作的类来封装类的实现,仅向用户提供类,即接口,该接口仅充当实现类的包装器.
例如:考虑一个为浮点运算实现极快堆栈的库.容器的界面非常简单:
class fast_stack
{
public:
void push( float );
float pop();
};
Run Code Online (Sandbox Code Playgroud)
但是由于这个库实现了极快的堆栈,它的实现基于极其复杂的库,内联汇编,brainfuck互操作性等.
该库的用户只想要一个堆栈,而不是一堆可怕的代码,库和依赖项.我们怎样才能隐藏所有的尖叫声,只为他提供一个简单而干净的界面?这就是PIMPL开始的地方:
//stack_inferno.hpp
#include <thread>
#include <Boost/ASIO>
... More monters here
class fast_stack_infernal_implementation
{
std::thread* _mptr_thread_lcl;
float******* _suicide_cache_memory_pool;
... etc etc
void push( float elem )
{
//Please don't see this code, it could hurt your eyes
}
float pop()
{
// Same as above
}
};
//fast_stack.hpp (Revisited)
class fast_stack_infernal_implementation; //Note the forward declaration.
class fast_stack
{
public:
void push( float );
float pop();
private:
std::unique_ptr<fast_stack_infernal_implementation> implm;
};
//fast_stack.cpp
#include "stack_inferno.hpp" //Tah daah!
fast_stack::fast_stack() : impl( new fast_stack_infernal_implementation() )
{
}
void fast_stack::push( float elem )
{
implm->push( elem );
}
float fast_stack::push()
{
return implm->pop();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,PIMPL习语具有许多优点:
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |