comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: smart pointer dangerous (no -> operator)
Date: Fri, 16 Jan 2009 12:09:16 +0100
Date: 2009-01-16T12:09:17+01:00	[thread overview]
Message-ID: <a8go9gb0a60q.wypnft0gfg98$.dlg@40tude.net> (raw)
In-Reply-To: gkpluq$vda$1@online.de

On Fri, 16 Jan 2009 11:04:57 +0100, Oliver Kowalke wrote:

> Ada doesn't support the dereference operator -> as C++.
> 
> So Ada provides only two ways to access the managed object?
> 
> - returning it via value : function Get(Pointer : Smart_Pointer) return
> Object;
> 
> - returning it via access type : function Get(Pointer : Smart_Pointer)
> return Access_Object;
> 
> - returning a proxy which implements the functions applicable to the managed
> object
> 
> In the first case I can not manipulate the state of the managed object
> (setting some internal data).
> The second case is dangerous because the ownership 'constraint' can be
> violated -> other code can call Unchecked_Delete on the returned access
> type or assign it to another one.
> 
> How can case three be implemented in Ada if the smart ponter package is
> generic?

It is difficult, since there is no any delegation support in Ada.

I extensively used two approaches:

1. In Ada 95 I declare the proxy type tagged controlled. The handle is
created through a instantiation in the private part of the generic package
Handle:

   type X_Handle is new Ada.Finalization.Controlled with private;
      -- Repeat all operations of the target
   procedure Foo (Object : X_Handle);
   ... -- and so on
private
   package Handles is not Object.Handle (...); -- Instantiation
   type X_Handle is new Handles.Handle with null record;

The implementation of Foo goes as follows:

   procedure Foo (Object : X_Handle) is
   begin
       Foo (Ptr (Object).all);
   end Foo;

this is extremely tedious, but the best way I know.

Important, the target object is derived from Object.Entity. This is
necessary for reference counting. There is also another base for
persistence support.

2. In Ada 2005 things are slightly better. There I use interfaces. The
target object receives an interface:

   type X_Interface is ...;
   procedure Foo (Object : X_Interface) is abstract;

Then I define the object's implementation type derived from Object.Entity
as before, but also implementing X_Interface. Usually I do it privately,
though this requires some additional efforts in package hierarchy
structuring (the proxy must see the object implementation type at the
handle instantiation point).

Now the proxy type:

   type X_Handle is new Ada.Finalization.Controlled
      and X_Interface with private;

No more need to repeat everything.

The implementation is still needed:

   procedure Foo (Object : X_Handle) is
   begin
      Ptr (Object).Foo; -- Using prefix notation
   end Foo;

This is less error prone, but still endlessly boring. Two major problems
are:

1. Lack of delegation in order to automate generation of wrappers like Foo.
2. Lack of MI, because one base type is required and used further extension
of the target type becomes practically impossible.

There also are more difficult problem of building hierarchies of proxy
types corresponding to the hierarchy of the targets as well as container
types for proxies. But this is another story.

---------------
P.S. My implementation of proxy object can be found here

http://www.dmitry-kazakov.de/ada/components.htm#Objects_etc

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2009-01-16 11:09 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-16 10:04 smart pointer dangerous (no -> operator) Oliver Kowalke
2009-01-16 11:09 ` Dmitry A. Kazakov [this message]
2009-01-16 11:42   ` Georg Bauhaus
2009-01-16 12:43     ` Dmitry A. Kazakov
2009-01-16 21:21     ` Maciej Sobczak
2009-01-17 19:07       ` Georg Bauhaus
2009-01-16 11:46   ` Oliver Kowalke
2009-01-16 12:45     ` Dmitry A. Kazakov
2009-01-17  0:43   ` Brian Drummond
2009-01-17  9:28     ` Dmitry A. Kazakov
2009-01-16 20:08 ` Tero Koskinen
2009-01-16 21:16   ` Maciej Sobczak
2009-01-18 12:21 ` Samuel Tardieu
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox