我有一个面向对象的设计如下(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;
第二个选项工作正常。
- 使用标准配置文件不会出现问题。我在(天真地)移植到特定配置文件时遇到了这个问题。据我所知,这是合法的面向对象设计,但有些结构的处理方式不同。
我的问题:
我的第二个选项可以接受吗?为什么它有效?
我错过了什么吗?我知道这与编译器生成的代码的调度表管理有些相关,但我并没有真正了解深层机制/原因。