我有一个像构造函数一样的函数规范。函数的规范是
function Create_Controller return Type_Controller;
另外,在规范文件中,我有Type_Controller类型,这是一个访问。我复制了相关的片段:
type Type_Controller_Implementation;
type Type_Controller is access Type_Controller_Implementation;
所以,这就是我的尝试:
function Create_Controller return Type_Controller
is
My_Controller : aliased Type_Controller_Implementation;
begin
return My_Controller'Access;
end Create_Controller;
我试图在没有别名关键字的情况下编译程序,但编译器说:
prefix of "Access" attribute must be aliased
所以,我把别名关键字和编译器现在建议我应该改变规范:
result must be general access type
add "all" to type "Controlador_De_Impresion" defined at controller.ads
问题在于我不允许更改规范。我已经阅读了Ada Programming Wikibook中关于访问类型的章节,但我仍然不明白为什么我的代码不起作用。我做错了什么?
答案 0 :(得分:3)
Create_Controller函数体的实现不正确。如果它以编码方式工作,你将返回一个指向变量 local 的指针到该函数体的范围......当从函数返回时会立即丢失,会留下无效的指针
不,需要分配和返回类型的实例。如果没有需要发生的显式初始化,您可以简单地执行:
return new Type_Controller_Implementation;
如果必须进行某些初始化/构造,则:
function Create_Controller return Type_Controller
is
My_Controller : Type_Controller := new Type_Controller_Implementation;
begin
-- Set fields of My_Controller
...
return My_Controller;
end Create_Controller;
答案 1 :(得分:0)
当您将访问类型声明为access T
时,您说“这是指向T
的指针,它必须指向从池中分配的T
类型的对象”。 (即,使用new
关键字进行分配。)当您将访问类型声明为access all T
时,您说它可以指向从池中分配的T
,< em>或到类型为T
的别名变量。
如果类型声明为access T
并且您无法更改它,则该类型的所有访问值都必须指向使用new
分配的内容。你不能指向一个变量(甚至是一个不在堆栈上的“全局”变量)。
我认为其原因是历史性的。 Ada的第一个版本(Ada 83)只有“特定于游泳池的类型”。您根本无法将access
值指向其他变量,而无需欺骗。这意味着编译器可以将访问值实现为某些存储块的索引,或者作为其他值,而不是使它们成为对象的实际地址。这可以节省空间(访问值可能小于地址)或允许更灵活地管理池内存。允许访问值直接指向对象会带来一些灵活性。我认为这就是为什么他们决定保留旧的含义,以实现向后兼容性,并且需要all
关键字来表示新的访问类型。