2017-10-19 49 views
1

我想创建和初始化以下方式控制的类型(有点像一个厂)创建一个函数:创作控制型将调用finalize在返回

function Create return Controlled_Type 
is 
    Foo : Controlled_Type; 
begin 
    Put_Line ("Check 1") 
    return Foo; 
end Create; 

procedure Main 
is 
    Bar : Controlled_Type := Create; 
begin 
    Put_Line ("Check 2") 
end Main; 

output: 
Initialize 
Check 1 
Adjust 
Finalize 

由于完成按钮将处置在控制类型I中指向的一些对象最终会在Bar中悬挂指针,并且不知何故,这会立即崩溃该程序,所以我从不会看到“Check 2”。

这可以通过使用新的Controlled_Type并在Create函数中返回一个指针来轻松解决。但是,我喜欢拥有受控类型的想法,而不是指向它的指针,因为当Bar超出范围时,会自动调用finalization。如果Bar是一个指针,我不得不手动处理它。

有什么办法可以正确地做到这一点,而不会结束悬挂指针?我应该在调整过程中做一些魔术吗?

回答

3

那么,你应该实施Adjust适当

制作副本时,它是按位进行的,因此原件中的任何指针都会原样复制到副本。当原始文件完成并且指出的对象被释放后,您将在副本中留下指向超空间的指针。

要做的事情是分配一个新的指针,指定与原始值相同的值。喜欢的东西

with Ada.Finalization; 
with Ada.Text_IO; use Ada.Text_IO; 
with Ada.Unchecked_Deallocation; 

procedure Finalart is 

    type Integer_P is access Integer; 
    type Controlled_Type is new Ada.Finalization.Controlled with record 
     P : Integer_P; 
    end record; 
    procedure Initialize (This : in out Controlled_Type); 
    procedure Adjust (This : in out Controlled_Type); 
    procedure Finalize (This : in out Controlled_Type); 

    procedure Initialize (This : in out Controlled_Type) is 
    begin 
     Put_Line ("initialize"); 
     This.P := new Integer'(42); 
    end Initialize; 

    procedure Adjust (This : in out Controlled_Type) is 
     Original_Value : constant Integer := This.P.all; 
    begin 
     Put_Line ("adjust"); 
     This.P := new Integer'(Original_Value); 
    end Adjust; 

    procedure Finalize (This : in out Controlled_Type) is 
     procedure Free is new Ada.Unchecked_Deallocation (Integer, Integer_P); 
    begin 
     Put_Line ("finalize"); 
     Free (This.P); 
    end Finalize; 

    function Create return Controlled_Type is 
     CT : Controlled_Type; 
    begin 
     Put_Line ("check 1"); 
     return CT; 
    end Create; 

    Bar : Controlled_Type := Create; 
begin 
    Put_Line ("check 2"); 
end Finalart; 

如果我在Adjust注释掉该行This.P := new Integer'(Original_Value);,我获得(在MacOS)

$ ./finalart 
initialize 
check 1 
adjust 
finalize 
adjust 
finalize 
finalart(35828,0x7fffd0f8b3c0) malloc: *** error for object 0x7fca61500000: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 

raised PROGRAM_ERROR : unhandled signal 
+0

非常感谢您为广大的答案,这真的帮助我了解如何实现调整程序。在我的具体情况下,我在主控制类型下有一个树形数据结构,需要一些递归调整过程,但最终它的功能就像一个魅力。 – FinalArt2005

相关问题