Re: smart pointer dangerous (no -> operator)
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Fri, 16 Jan 2009 12:09:16 +0100
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
.
- Follow-Ups:
- Re: smart pointer dangerous (no -> operator)
- From: Brian Drummond
- Re: smart pointer dangerous (no -> operator)
- From: Oliver Kowalke
- Re: smart pointer dangerous (no -> operator)
- From: Georg Bauhaus
- Re: smart pointer dangerous (no -> operator)
- References:
- smart pointer dangerous (no -> operator)
- From: Oliver Kowalke
- smart pointer dangerous (no -> operator)
- Prev by Date: Re: How to put 200 into an integer sub-type of 16 bits (code included)
- Next by Date: Re: smart pointer dangerous (no -> operator)
- Previous by thread: smart pointer dangerous (no -> operator)
- Next by thread: Re: smart pointer dangerous (no -> operator)
- Index(es):
Relevant Pages
|