Meh*_*ada 0 generics packages ada package
在Ada中这很简单:
type ITEM_RECORD;
type ITEM_ACCESS is access ITEM_RECORD;
type ITEM_RECORD Is
record
ITEM: item_type;
Next: item_access;
Pred: item_access;
end record;
Run Code Online (Sandbox Code Playgroud)
容易,对吗?现在,如果我想让ITEM_ACCESS成为通用包中声明的智能/安全指针,该怎么办?我直觉地这样做,只要它有效:
type ITEM_access;
type Item_Record is record
Item : Item_Type;
Next : Item_Access;
Pred : Item_Access;
end record;
type pointers_on_record is access Item_record;
package pointers_p is new pointers(Item_Record, pointers_on_record);
type item_access is new pointers_p.Pointer_Type;
Run Code Online (Sandbox Code Playgroud)
通用的规格如下:
generic
type Item_Type(<>) is limited private;
type Access_Type is access Item_Type;
package Pointers is
type Pointer_Type is private;
Run Code Online (Sandbox Code Playgroud)
我还没想出怎么做.
谢谢 !
由于循环依赖性,您无法创建要创建的结构.想一想:
通用包定义了一个指针.Pointer_Type(可能)的结构和实现取决于泛型参数Item_Type(这不一定是真的,但如果不是,则不需要Item_Type作为通用参数).现在,Item_Type在你的泛型包的实例化中包含来自泛型包的两个智能指针,因此,取决于它的结构Pointer_Type.这是一个经典的鸡蛋或鸡蛋问题.
所以解决方案是改变你的类型的设计.让我给你一些指示(没有双关语):
看起来你正在实现一个双向链表.请注意,由于列表的循环特性,使用实现引用计数的智能指针是一个严重的错误.如果你的列表至少包含两个项目,那么任何东西都不会被释放,因为它们总是指向对方.因此,除非您的智能指针正在进行循环检测(根据您的规范无法实现),否则您无法按照自己的方式使用智能指针.
一个可能的解决方案是拥有智能指针Item_Type,而不是记录.您需要手动取消分配记录,但无论如何,您需要执行此操作,如上所述.
另一种解决方案是为整个列表提供一个全局引用计数器.创建一个不透明的列表类型,为列表提供访问器和迭代器子例程,分发项目的智能指针.智能指针增加和减少整个列表上的引用计数,一旦对列表的最后一次引用消失,整个列表将被释放.因此,只要存在至少一个对其中某些内容的引用,该列表就存在.此解决方案需要您自己实现引用计数,因为它专门用于列表结构.
最后,你可以使用Ada.Containers.Doubly_Linked_Lists,就像Jeffrey建议的那样.Item_Type正如我在第一个解决方案中所建议的那样,您可以将智能指针放在那里.