Pimpl成语不使用动态内存分配 [英] Pimpl idiom without using dynamic memory allocation

查看:130
本文介绍了Pimpl成语不使用动态内存分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们想对我们项目的某些部分使用pimpl成语。项目的这些部分也恰好是禁止动态内存分配的部分,这个决定不在我们的控制之中。



所以我要问的是,是否有一个干净,漂亮的方式实现pimpl成语没有动态内存分配?



编辑

这里有一些其他限制:嵌入式平台,标准C ++ 98,没有外部库,没有模板。

解决方案

警告:这里的代码只显示存储方面,它是一个骨架,没有考虑到动态方面(构造,复制,移动,销毁)。 / p>

我建议使用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;
};

然后在源代码中执行检查:

  struct Foo :: Impl {...}; 

Foo :: Foo()
{
// 10%公差裕度
static_assert(sizeof(Impl)< = StorageSize&& StorageSize< = sizeof(Impl)* 1.1,
Foo :: StorageSize need be changed);
static_assert(StorageAlign == alignof(Impl),
Foo :: StorageAlign需要更改);
/// anything
}

这样,立即更改对齐(如果必要),只有对象更改过多时,大小才会更改。



显然,由于检查是在编译时, miss it:)



如果您没有访问C ++ 0x功能,TR1命名空间中存在 aligned_storage alignof ,并且有一些宏实现 static_assert


we want to use pimpl idiom for certain parts of our project. These parts of the project also happen to be parts where dynamic memory allocation is forbidden and this decision is not in our control.

So what i am asking is, is there a clean and nice way of implementing pimpl idiom without dynamic memory allocation?

Edit
Here are some other limitations: Embedded platform, Standard C++98, no external libraries, no templates.

解决方案

Warning: the code here only showcases the storage aspect, it is a skeleton, no dynamic aspect (construction, copy, move, destruction) has been taken into account.

I would suggest an approach using the C++0x new class aligned_storage, which is precisely meant for having raw 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;
};

In the source, you then implement a check:

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
}

This way, while you'll have to change the alignment immediately (if necessary) the size will only change if the object changes too much.

And obviously, since the check is at compilation time, you just cannot miss it :)

If you do not have access to C++0x features, there are equivalents in the TR1 namespace for aligned_storage and alignof and there are macros implementations of static_assert.

这篇关于Pimpl成语不使用动态内存分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆