Ada 中的新放置相当于什么?

GDI*_*512 2 c++ memory-management ada

我试图通过编写一组管理动态数组的过程来学习 Ada,但我不知道如何去做。在 C++ 中,我可以轻松地将任意对象放入内存中,如下所示:

#include <new>
#include <iostream>

class object {
  private:
    int value;

  public:
    ~object() noexcept { std::cout << "<> "; }
    object(int value) noexcept : value(value) { std::cout << object::value << ' '; }
};

constexpr auto size = 16;

int main() {
    auto buffer = static_cast<object*>(::operator new(size * sizeof(object)));
    for (auto offset = 0; offset < size; offset++)
        new (buffer + offset) object(offset);
    for (auto offset = 0; offset < size; offset++)
        (buffer + offset)->~object();
    ::operator delete(buffer);
}
Run Code Online (Sandbox Code Playgroud)

Ada 中是否存在与此类“分配 x * sizeof(y) 并初始化 x y-items”操作等效的操作?

Max*_*nik 5

在 Ada 中,您可以编写自定义“存储池”(或子池),在其中重新定义分配函数以使用缓冲区。然后,您将访问类型“绑定”到存储池对象。

with System.Storage_Pools;
with System.Storage_Elements;

procedure Main is
   type My_Storage_Pool is new System.Storage_Pools.Root_Storage_Pool with record
      Buffer : System.Storage_Elements.Storage_Array (1 .. 1024);
      Offset : System.Storage_Elements.Storage_Count := 1;
   end record;

   overriding procedure Allocate
     (Self      : in out My_Storage_Pool;
      Address   : out System.Address;
      Size      : System.Storage_Elements.Storage_Count;
      Alignment : System.Storage_Elements.Storage_Count);
   
   overriding procedure Deallocate
     (Self      : in out My_Storage_Pool;
      Address   : System.Address;
      Size      : System.Storage_Elements.Storage_Count;
      Alignment : System.Storage_Elements.Storage_Count) is null;

   overriding function Storage_Size
     (Self : My_Storage_Pool)
      return System.Storage_Elements.Storage_Count is (Self.Buffer'Length);
   
   procedure Allocate
     (Self      : in out My_Storage_Pool;
      Address   : out System.Address;
      Size      : System.Storage_Elements.Storage_Count;
      Alignment : System.Storage_Elements.Storage_Count)
   is
      use type System.Storage_Elements.Storage_Count;
   begin
      Address := Self.Buffer (Self.Offset)'Address;
      Self.Offset := Self.Offset + Size;
   end Allocate;
   
   Pool : My_Storage_Pool;
   
   type Object is null record;
   type Object_Access is access Object with Storage_Pool => Pool;

   X : Object_Access := new Object;
begin
   null;
end Main;
Run Code Online (Sandbox Code Playgroud)

此外,对于未标记的类型,您可以使用Address子句将对象放置到给定地址。这个就简单多了。但这样对象初始化将不起作用,因此标记类型对象将无法获得虚拟表指针:

Buffer : Stream_Element_Array (1..1024);
Object : My_Object_Type
  with Import, Address => Buffer (Offset)'Address;
--  Here Object'Tag is unassigned and dispatching won't work
Run Code Online (Sandbox Code Playgroud)