返回对Ada中成员变量的常量引用

时间:2018-06-12 09:37:53

标签: pointers ada

我在Ada中有一个包含矩阵的类。我想实现一个函数,将其作为constant access类型返回,只是为了能够将其作为只读值,但避免不必要的副本。

我已经通过返回对Integer的引用来尝试它,仅用于测试目的:

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;

以上不会编译,错误是:non-local pointer cannot point to local object.

我的问题是:

为什么我得到那个错误?

有没有办法实现我想要的,而不使用Unchecked_Access

我是否真的需要返回变量的引用,或者Ada编译器可以优化副本?

3 个答案:

答案 0 :(得分:3)

通过结合Ada 2005和#34;中引入的匿名访问类型,在Ada 2012中引入了安全引用。和Ada 2012中引入的" Implicit_Dereference方面"不久之后在这里描述:

https://www.adacore.com/gems/gem-123-implicit-dereferencing-in-ada-2012

Dan,根据您的具体情况

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;

如果您尝试通过"变量。测试:= 1;"设置私有变量。你将得到编译时错误,因为你只有一个Integer的只读视图。

答案 1 :(得分:2)

制作参数aliased

function Test(Self : aliased in B) return access constant Integer;

(强制参数通过引用ARM 6.2(3)

传递

答案 2 :(得分:1)

您收到错误消息,因为编译器无法保证在超出范围/消失后您无法保留对该实体的引用。

方面Implicit_Dereference有一些技巧可以解决你的问题。