Ada子包无法访问父包私有类型:问题排查与重构方案咨询
Ada父包私有类型对子包的访问解决方案
针对你遇到的子包无法访问父包私有类型的问题,有两种符合封装要求的重构方案,均适配GNAT 13.2.0版本:
方案1:使用私有子包(Private Child Package)
Ada的私有子包天生具备访问父包私有部分的权限,无需修改父包的私有类型声明。
步骤:
- 修改子包
AES.AES_Cipher的规范文件(aes-aes_cipher.ads),将开头的package改为private package:private package AES.AES_Cipher is -- 直接使用父包的私有类型State、Key_Schedule function Cipher(S : State; KS : Key_Schedule) return State; end AES.AES_Cipher; - 父包
AES的规范(aes.ads)无需额外修改,保持原有私有类型声明即可:package AES is -- 公有类型 type Byte is mod 256; type Input_Buffer is array(Positive range <>) of Byte; -- 私有类型声明 type State is private; type Key_Schedule is private; -- 父包的其他公有操作 private -- State和Key_Schedule的具体实现 type State is array(0..3, 0..3) of Byte; type Key_Schedule is array(0..39) of Byte; end AES; - 父包体(
aes.adb)调用子包的逻辑保持不变,编译时GNAT会自动识别私有子包的权限。
方案2:使用Ada 2012的private with特性(推荐)
如果不想将子包设为私有子包,可以用private with让特定子包单独访问父包的私有部分,更灵活。
步骤:
- 在父包
AES的规范开头添加private with声明,指定允许访问私有部分的子包:private with AES.AES_Cipher; package AES is -- 公有类型 type Byte is mod 256; type Input_Buffer is array(Positive range <>) of Byte; -- 私有类型声明 type State is private; type Key_Schedule is private; -- 父包的其他公有操作 private -- State和Key_Schedule的具体实现 type State is array(0..3, 0..3) of Byte; type Key_Schedule is array(0..39) of Byte; end AES; - 子包
AES.AES_Cipher的规范保持普通子包形式,直接引用父包的私有类型:package AES.AES_Cipher is function Cipher(S : AES.State; KS : AES.Key_Schedule) return AES.State; end AES.AES_Cipher; - 编译时使用GNAT默认的Ada 2012及以上模式即可,无需额外参数。
关键说明
- 两种方案都能保证
State和Key_Schedule对外保持私有,只有指定的子包可以访问。 - 不要通过移除
private关键字暴露私有类型,这会破坏封装性,违背设计初衷。 - GNAT 13.2.0完全支持上述两种特性,直接用
gnatmake aes.adb即可完成编译。
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

