Ada中如何禁止子包直接修改Item记录且保留调用私有Set方法权限
问题背景
你给出的Parent包默认情况下,Ada的可见性规则允许Parent的所有子包访问父包私有部分的所有内容,也就是说子包既可以直接读写Item的Value字段,也可以调用Set过程,不符合你的要求。
实现方案
你可以通过两种符合Ada标准的方式实现需求,既禁止子包直接修改Item的字段,又保留子包调用Set的能力:
方案1:Ada 95+兼容的私有子包拆分法
该方案兼容所有现代Ada版本,核心是将Item的内部结构封装到仅Parent包可见的私有子包中:
- 首先创建Parent的私有子包
Parent.Internal,存放Item的完整定义:
private package Parent.Internal is type Item is record Value : Boolean; end record; end Parent.Internal;
- 修改原Parent包的定义,私有引入该内部子包,将
Item声明为私有派生类型:
with Parent.Internal; package Parent is type Item is private; function Get return Item; private -- 私有派生类型,子包无法访问基类的内部结构 type Item is new Parent.Internal.Item; procedure Set (Object : in out Item; -- 注意:原代码Object为in模式无法修改,建议改为in out Value : Boolean); end Parent;
此时Parent的普通子包只能看到私有部分的Set声明,无法访问Parent.Internal的内容,自然不能直接操作Value字段,调用Set的能力完全保留。
方案2:Ada 2012+简洁私有嵌套声明法
如果你使用Ada 2012及更高版本,可以直接用私有部分嵌套private的语法,将Item的结构标记为仅Parent包自身可见,子包无访问权限:
package Parent is type Item is private; function Get return Item; private -- 这一层的声明对所有子包可见 procedure Set (Object : in out Item; Value : Boolean); -- 嵌套的private层,仅当前包自身可见,子包无法访问 private type Item is record Value : Boolean; end record; end Parent;
该方案无需额外创建子包,代码更简洁,修改后子包尝试直接访问Value字段时编译器会直接抛出可见性错误。
补充说明
你原代码中的Set过程Object参数为in模式,无法修改传入的Item实参,如果Set的作用是修改Item的取值,记得将参数调整为in out模式。
内容的提问来源于stack exchange,提问作者user15552120
相关产品推荐
相关产品推荐

