Pointers 返回对Ada中成员变量的常量引用
我在Ada中有一个包含矩阵的类。我想实现一个函数,将其作为Pointers 返回对Ada中成员变量的常量引用,pointers,ada,Pointers,Ada,我在Ada中有一个包含矩阵的类。我想实现一个函数,将其作为常量访问类型返回,以便能够将其作为只读值获取,但避免不必要的复制 我尝试过返回一个整数的引用,只是为了测试: package Tests_Package is type B is private; function Test(Self : in B) return access constant Integer; private type B is tagged record
常量访问
类型返回,以便能够将其作为只读值获取,但避免不必要的复制
我尝试过返回一个整数的引用,只是为了测试:
package Tests_Package is
type B is private;
function Test(Self : in B) return access constant Integer;
private
type B is tagged
record
I : aliased Integer;
end record;
end Tests_Package;
-------------------------------------------
package body Tests_Package is
function Test(Self : in B) return access constant Integer is
begin
return Self.I'access;
end Test;
end Tests_Package;
以上内容将无法编译,错误是:非本地指针不能指向本地对象。
我的问题是:
为什么我会犯这样的错误
是否有任何方法可以实现我想要的,而不使用未选中的访问
我是否真的需要返回变量的引用,或者Ada编译器可以优化副本?您会收到错误消息,因为编译器无法保证在实体超出范围/消失后无法保留对该实体的引用
aspect
隐式\u Dereference
有一些技巧,可以解决您的问题。您会收到错误消息,因为编译器无法保证在实体超出范围/消失后无法保留对它的引用
aspect
隐式解引用有一些技巧,可以解决您的问题。将参数设置为别名
:
function Test(Self : aliased in B) return access constant Integer;
(这将强制通过引用传递参数,使参数具有别名
:
function Test(Self : aliased in B) return access constant Integer;
(强制通过引用传递参数,安全引用是在Ada 2012中通过结合“Ada 2005中引入的匿名访问类型”和“Ada 2012中引入的隐式解引用方面”引入的,并在此处简要介绍:
丹,在你的特殊情况下
package Tests_Package is
type Integer_Ref
(Element : not null access constant Integer) is limited null record with
Implicit_Dereference => Element;
type B is tagged private;
function Test (Self : aliased B) return Integer_Ref;
private
type B is tagged
record
I : aliased Integer := 5;
end record;
function Test (Self : aliased B) return Integer_Ref is
((Element => Self.I'Access));
end Tests_Package;
它的用法如下:
with Tests_Package;
with Ada.Text_IO;
procedure Main is
Variable : Tests_Package.B;
Result : Integer := 3 + Variable.Test;
begin
Ada.Text_IO.Put_Line (Result'Img);
end Main;
如果您尝试通过“variable.Test:=1”设置私有变量,您将得到编译时错误,因为您只有整数的只读视图。安全引用是在Ada 2012中通过结合“Ada 2005中引入的匿名访问类型”和“Ada 2012中引入的隐式引用方面”引入的并在这里简要介绍:
丹,在你的特殊情况下
package Tests_Package is
type Integer_Ref
(Element : not null access constant Integer) is limited null record with
Implicit_Dereference => Element;
type B is tagged private;
function Test (Self : aliased B) return Integer_Ref;
private
type B is tagged
record
I : aliased Integer := 5;
end record;
function Test (Self : aliased B) return Integer_Ref is
((Element => Self.I'Access));
end Tests_Package;
它的用法如下:
with Tests_Package;
with Ada.Text_IO;
procedure Main is
Variable : Tests_Package.B;
Result : Integer := 3 + Variable.Test;
begin
Ada.Text_IO.Put_Line (Result'Img);
end Main;
如果您尝试通过“variable.Test:=1”设置私有变量,您将得到编译时错误,因为您只有整数的只读视图。您的代码+我的修改使用GCC 6、7、8和GNAT CE 2016、2017、2018进行编译。不知道区别是什么(当然,您的类型B已标记,因此它仍然是通过引用进行的。哈。)你的代码+我的修改使用GCC 6、7、8和GNAT CE 2016、2017、2018进行编译。不知道区别是什么(当然,你的类型B是有标签的,所以它是通过引用的。哈。)副本可以进行优化。除非您在满足预先指定的定量计时要求方面有明显的失败,否则您不应该担心它。在这种特殊情况下,函数的Self
参数是按值传递的。这意味着编译器将创建传递值的
本地副本。当ion返回时,此本地副本不再存在;因此,返回的地址无效。要使其正常工作,可以将此值作为access
(C/C++中的指针)传递。可以对副本进行优化。除非您在满足预先指定的定量计时要求方面存在明显的失败,否则您不必担心它。在这种特殊情况下,函数的Self
参数是按值传递的。这意味着编译器将创建传递值的
本地副本tion返回时,此本地副本不再存在;因此,返回的地址无效。若要使其正常工作,可以将此值作为access
(C/C++中的指针)传递。