代码之家  ›  专栏  ›  技术社区  ›  dicroce

C++中显式禁用堆分配

  •  14
  • dicroce  · 技术社区  · 15 年前

    我有许多类要明确地禁止为其分配堆。这个周末我突然想到我可以宣布接线员为新的私人人员(而且还没有实现)。当然,当您尝试新建类时,这会导致编译错误…我的问题是:还有别的吗?我是错过了什么,还是这是做我想做的事情的好方法?

    #include <stdio.h>
    
    class NotOnTheHeap
    {
    public:
      NotOnTheHeap() : foo( 0 )
      {
      }
    
    private:
      void *operator new( size_t );
      void operator delete( void* );
      void *operator new[]( size_t );
      void operator delete[]( void* );
    
      int foo;
    };
    
    class Heapable
    {
    private:
      NotOnTheHeap noth;
    };
    
    int main( int argc, char* argv[] )
    {
      NotOnTheHeap noth;
    
      Heapable* heapable = new Heapable;
    
      return 0;
    }
    
    4 回复  |  直到 15 年前
        1
  •  11
  •   Michael Myers KitsuneYMG    15 年前

    取决于“显式不允许堆分配”的含义。

    如果您只想防止堆上的直接分配,即:

    NotOnTheHeap *n = new NotOnTheHeap();
    

    这足够好了。但它不会阻止您的对象一般存在于堆中。

    例如,它不会阻止人们使用 std::vector <NotOnTheHeap> ,它将从堆上的类中分配对象。

    它也不会阻止人们使用 NotOnTheHeap 作为另一个类中的成员变量,在堆上分配。

        2
  •  1
  •   Drew Dormann    15 年前

    这将主要实现你所尝试的。

    您的解决方案没有涵盖的是新的,可能在堆中,也可能不在堆中。

        3
  •  1
  •   rama-jka toti    15 年前

    对于更严格的场景(某些情况下嵌入值或容器的使用),可以禁用copy或甚至默认构造,以及operator=etc。

    但是,这将使您摆脱一些有用的构造,并强制您引入自己的语义(在VM IMPLS中更明显的东西;缺少/归纳类似的运算符和不明确的等价/相等机制)。您可能也会看到一些编译器警告,它不会一直运行,但是如果有任何安慰,它可以有一两个用途。

        4
  •  0
  •   dsimcha    15 年前

    不能让运算符new的实现成为assert(0)?