【发布时间】:2018-06-12 13:25:30
【问题描述】:
我的面向对象设计如下(Ada 2012)。 问题不在于设计本身,而在于它对特定运行时配置文件的影响。
-- several packages ommitted here, ads/adb mixed together
type Interface_A is interface;
type Interface_A_Class_Access is access all Interface_A'Class;
type Interface_B is interface and Interface_A;
type Interface_B_Class_Access is access all Interface_B'Class;
type Interface_C is interface and Interface_B
type Interface_C_Class_Access is access all Interface_C'Class;
type B_Impl is abstract tagged ...;
type B_Impl_Access is access all B_Impl;
type C_Impl is new B_Impl and Interface_C ...;
type C_Impl_Access is access all C_Impl;
function Create_C return C_Impl_Access is begin
return new C_Impl'(...);
end Create;
我有一个工厂来实例化 Interface_A、Interface_B 或 Interface_C 的对象。
package body My_Factory is
procedure Create_A return Interface_A_Class_Access is begin
return Create_A_Impl; -- error: dynamic interface conversion not supported by configuration
end Create_B;
procedure Create_B return Interface_B_Class_Access is begin
return Create_C_Impl; -- error: dynamic interface conversion not supported by configuration
end Create_B;
procedure Create_C return Interface_C_Class_Access is begin
return Create_C_Impl; -- error: dynamic interface conversion not supported by configuration
end Create_C;
end package My_Factory;
使用我的开关,两个工厂创建功能都出现以下错误:
error: dynamic interface conversion not supported by configuration
环境:
- GNAT 17.2
- ZFP MPC8641
- GPRBUILD Pro 18+
到目前为止我尝试了什么:
- 使用显式强制转换或显式临时变量分配更改工厂实现:
示例:
package body My_Factory is
...
procedure Create_B return Interface_B_Class_Access is begin
return Interface_B_Class_Access(Create_C); -- error: dynamic interface conversion not supported by configuration
end Create_B;
procedure Create_C return Interface_C_Class_Access is
tmp : Interface_C_Class_Access;
begin
tmp := Create_C; -- error: dynamic interface conversion not supported by configuration
return tmp;
end Create_C;
end package My_Factory;
同样的问题。
- 添加显式构造方法(将“新”影响到类访问变量中)
示例:
function Create_C return Interface_A_Class_Access is begin
return new C_Impl'(...); -- error: dynamic interface conversion not supported by configuration
end Create;
function Create_C return Interface_B_Class_Access is
tmp : Interface_B_Class_Access;
begin
tmp := new C_Impl'(...); -- works fine
return tmp;
end Create;
function Create_C return Interface_C_Class_Access is
tmp : Interface_B_Class_Access;
begin
tmp := new C_Impl'(...); -- works fine
return tmp;
end Create;
第二个选项效果很好。
- 使用标准配置文件不会出现问题。我在(天真地)移植到特定配置文件时遇到了这个问题。据我了解,这是合法的面向对象设计,但有些结构的处理方式不同。
我的问题:
我的第二个选项可以接受吗?为什么会起作用?
我错过了什么吗?我知道这与编译器生成代码的调度表管理有些相关,但我并没有真正了解深层机制/原因。
【问题讨论】:
-
为什么要使用显式访问类型?
-
如果您能告诉我们您被限制在哪个个人资料中,这可能会有所帮助。
-
显式访问类型是项目的编码习惯,我想避免“匿名访问类型”。对于个人资料,我相信这包含在
ZFP MPC8641中。 -
我通常的建议是完全避免访问类型(容器内部除外)。
-
@JacobSparre-atCLDK 然而,避免访问类型并不会改变观察到的行为
标签: oop interface ada dispatch ada2012