ere*_*der 28 c++ embedded pimpl-idiom dynamic-memory-allocation
我们想在项目的某些部分使用pimpl习语.项目的这些部分也恰好是禁止动态内存分配的部分,这个决定不在我们的控制范围内.
所以我要问的是,在没有动态内存分配的情况下,有没有一种干净又好的方法来实现pimpl习语?
编辑
以下是一些其他限制:嵌入式平台,标准C++ 98,没有外部库,没有模板.
Mat*_* M. 25
警告:此处的代码仅显示存储方面,它是一个骨架,没有动态方面(构造,复制,移动,销毁)已被考虑在内.
我建议使用C++ 0x新类的方法aligned_storage
,这正是为了拥有原始存储.
// header
class Foo
{
public:
private:
struct Impl;
Impl& impl() { return reinterpret_cast<Impl&>(_storage); }
Impl const& impl() const { return reinterpret_cast<Impl const&>(_storage); }
static const size_t StorageSize = XXX;
static const size_t StorageAlign = YYY;
std::aligned_storage<StorageSize, StorageAlign>::type _storage;
};
Run Code Online (Sandbox Code Playgroud)
在源代码中,然后执行检查:
struct Foo::Impl { ... };
Foo::Foo()
{
// 10% tolerance margin
static_assert(sizeof(Impl) <= StorageSize && StorageSize <= sizeof(Impl) * 1.1,
"Foo::StorageSize need be changed");
static_assert(StorageAlign == alignof(Impl),
"Foo::StorageAlign need be changed");
/// anything
}
Run Code Online (Sandbox Code Playgroud)
这样,虽然您必须立即更改对齐(如果需要),但只有在对象更改太多时才会更改大小.
显然,由于检查是在编译时,你不能错过它:)
如果您无法访问C++ 0x功能,则TR1名称空间中有等效项aligned_storage
,alignof
并且存在宏的实现static_assert
.
pimpl基于指针,您可以将它们设置到分配对象的任何位置.这也可以是cpp文件中声明的对象的静态表.pimpl的要点是保持接口稳定并隐藏实现(及其使用的类型).