代码之家  ›  专栏  ›  技术社区  ›  Dan

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

  •  0
  • Dan  · 技术社区  · 7 年前

    我在ada中有一个包含矩阵的类。我想实现一个函数,它返回一个 constant access 键入,以便能够将其作为只读值获取,但避免不必要的复制。

    我尝试过返回对整数的引用以进行测试:

    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 回复  |  直到 7 年前
        1
  •  3
  •   Joakim Strandberg    7 年前

    ADA 2012中通过结合“ADA 2005中引入的匿名访问类型”和“ADA 2012中引入的隐式解引用方面”引入了安全引用,并在下面简要介绍:

    https://www.adacore.com/gems/gem-123-implicit-dereferencing-in-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”设置私有变量,则会出现编译时错误,因为您只有整数的只读视图。

        2
  •  2
  •   Simon Wright    7 年前

    设置参数 aliased :

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

    (它强制通过引用传递参数, ARM 6.2(3)

        3
  •  1
  •   Jacob Sparre - at CLDK    7 年前

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

    这方面有一些技巧 Implicit_Dereference ,这应该能解决你的问题。