gpt4 book ai didi

visibility - 从子包中隐藏记录

转载 作者:行者123 更新时间:2023-12-05 09:31:20 25 4
gpt4 key购买 nike

package Parent is

type Item is private;

function Get return Item;

private

type Item is
record
Value : Boolean;
end record;

procedure Set
(Object : Item;
Value : Boolean);

end Parent;

请告诉我在这个例子中如何防止直接从子包更改 Item 记录,从而保留调用私有(private)方法 Set 的能力?

最佳答案

这是我对 Ada 的提示之一(只是极少数之一),它允许人们简单地通过为您的包制作子包来绕过隐私。我没有弄乱私有(private)子包来查看我是否可以做一些工作,但是如果您对堆分配没问题,PIMPL 模式在 Ada 中确实有效。

基本上,您在包规范中创建了一个不完整的类型,并在私有(private)记录声明中使用了该类型的访问参数。规范不知道记录不完整类型是什么样的,但由于您只使用对它的访问类型,规范将编译。还应该隐藏所有需要的私有(private)操作,例如仅将 Set 隐藏到包体中。

然后在包体中完全定义不完整类型,我建议使用 Ada.Finalization 来确保参数始终被完全分配和释放。

我将给出一个完全可编译的示例(使用在线 tutorialspoint ada 编译器测试)。

我也不知道如何处理您的 Get 操作,所以只是将其默认为某些内容并添加了 Get_Value 操作以获取 bool 值。您可以根据需要删除/调整它。

这不是最通用的解决方法,但它是我发现在 Ada 中有效的解决方法。同样,我还没有探索“私有(private)”子包以查看它们是否可以以这种方式发挥作用,所以也许可以探索一些东西。

with Ada.Finalization;
with Ada.Unchecked_Deallocation;

with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is

package Parent is

type Item is tagged private;

function Get return Item;
function Get_Value(Self : in Item) return Boolean;

private

type Private_Item;
type Private_Access is access Private_Item;

type Item is new Ada.Finalization.Controlled with record
Impl : Private_Access := null;
end record;

overriding procedure Initialize(Self : in out Item);
overriding procedure Finalize(Self : in out Item);

end Parent;

package body Parent is

type Private_Item is record
Value : Boolean := False;
end record;

procedure Set
(Object : in out Item;
Value : Boolean)
is begin
Object.Impl.Value := Value;
end Set;

-- What is this supposed to do????
function Get return Item is (Ada.Finalization.Controlled with Impl => new Private_Item);

function Get_Value(Self : in Item) return Boolean is
begin
return Self.Impl.value; -- raises null exception if not initialized
end Get_Value;


procedure Initialize(Self : in out Item) is
begin
if Self.Impl = null then
Self.Impl := new Private_Item;
end if;
end Initialize;

procedure Free is new Ada.Unchecked_Deallocation(Private_Item, Private_Access);

procedure Finalize(Self : in out Item) is
begin
if Self.Impl /= null then
Free(Self.Impl);
end if;
end Finalize;

end Parent;

I : Parent.Item;

begin
Put_Line("Hello, world!");
Put_Line(Boolean'Image(I.Get_Value));
end Hello;

关于visibility - 从子包中隐藏记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68838455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com