如何将对象放在堆之外的其他地方?

时间:2012-03-15 08:08:25

标签: c++ dynamic heap

我们可以在堆之外的其他地方放置动态分配的对象吗?我将如何定义一个重载的新运算符?

如果我有类竞技场

 class Arena{
      char area[2000];
 public:
      Arena(){}
 };

Arena my_arena(1000);

我想从Arena my_arena分配对象..

此外,与在性能等上从堆分配相比,此类内存分配可能存在哪些缺点?

3 个答案:

答案 0 :(得分:5)

您可以轻松地使用新的展示位置:

MyClass* p = new (area) MyClass;

然而,您必须注意两个问题:

  1. 无法保证“area”将正确对齐 `MyClass`。我通常通过联盟来解决这个问题:
        union
        {
            double dummyForAlignment;
            //  Any other types which might be necessary...
            unsigned char area[2000];
        };
    
    这是非常特别的;对于你的类型,没有正式的保证 必须添加以确定。在实践中,我使用联合而不是“双” 大多数基本类型,加上几个指针,只是为了确定。
  2. 因为您使用了new,所以编译器不会处理 对你的破坏,就像普通数据成员一样。你会的 明确调用析构函数:
        p->~MyClass();
    
    这意味着您必须跟踪有多少对象 类型,以及已分配的位置。
  3. 这项技术的缺点是我刚才提到的两点。 另外,除非你保留一个指向构造对象的类型指针,否则你可以 在调试器中查看它们时遇到问题。 不过,对于某些特定用途来说,它是一种有用的技术:我在我的使用中使用它 Fallible类,以避免需要默认构造函数;该 标准容器需要它,当然还有预标准矢量或 数组类通常也使用它。它对各种用途也很有用 变体类;我认为它在boost::variant中使用,例如。

答案 1 :(得分:1)

这是可能的,但相当低级。

詹姆斯充分报道了C ++ 03自己做的代码,所以让我提出替代方案。

首先,在C ++ 03中,你有两个选择Boost:

  • Boost.Optionalboost::optional<MyClass>顾名思义允许您拥有(或不拥有)该类型的实例。
  • Boost.Variantboost::variant<SomeClass,OtherClass,YetAnotherClass>这是一种具有类型安全语义且保证构造函数/析构函数调用的union

其次,在C ++ 11中引入了std::aligned_storage<Len,Align>,它有两个参数:

  • 所需的存储字节数
  • 需要对齐

它使用暗编译器魔法来保证对齐得到满足,因此它是构建原始内存操作例程的良好基础。

就我个人而言,我个人会选择boost::optional

boost::optional<MyClass> Arena[256];

此模型完全符合您的要求,因为默认情况下boost::optional已实例化为空

答案 2 :(得分:0)

你可以简单地重载operator new&amp; delete并在堆栈上声明变量/ class。

或者,您可能希望使用某种静态池,以便静态管理它们。