Re: C++/CLI is the way to go
- From: Andre Kaufmann <andre.kaufmann_re_move_@xxxxxxxxxxx>
- Date: Sat, 20 Jan 2007 20:24:09 +0100
Philip Daniels wrote:
Sorry this time my post is a bit longer - had to post code too for illustration.
On Sat, 20 Jan 2007 18:05:44 +0100, Andre Kaufmann
<andre.kaufmann_re_move_@xxxxxxxxxxx> wrote:
[...]
Andre
I think that what Jon is saying is that ultimately in the CLR every
reference type "is" a System.Object, hence any solution using a
smartptr ultimately begs the question.
Yes know that.
The CLR has to constantly check
whether an object is a smartptr before it can do "the right thing".
Don't think so.
Arguments:
1) How does the CLR check the objects type when I
add it to a generic list ? They are all objects ?
How can it be typesafe ?
2) I can implement smart pointers in C++/CLI. How is that possible
the C++/CLI code is compiled to IL code ?
3) ! The killer argument ;-9
Delphi implements reference counted objects. InterfacedObjects
AFAIK this Delphi code
compiles directly without a modification
to .NET 1.1 ? How can this be ?
It's not just our code that would be a problem, I am sure there are
many places deep in the .Net runtime where objects are treated in a
generic fashion.
Yes, but why care about it ?
Sample code which illustrates the idea:
(There are many optimizations missing and which are essential for a good smart pointer object !!! - and I haven't tested the code !!!!)
-----------------------------------------------------
##### 1 Embedded counter implementation
########################################
class ReferenceCounter { public long value = 0; }
class SmartPointer<T> : IDisposable where T : class, IDisposable
{
public SmartPointer(T initialPtr)
{
stored = initialPtr;
refcounter.value = 1;
}
public SmartPointer()
{
stored = null;
refcounter.value = 1;
}
public void Assign(SmartPointer<T> r)
{
Discard();
refcounter = r.refcounter;
stored = r.stored;
refcounter.value++;
}
public void Assign(T r)
{
if (stored == r) return;
Discard();
stored = r;
refcounter.value = 1;
}
public void Discard()
{
if (--refcounter.value == 0)
if (stored != null) stored.Dispose();
}
public void Dispose() { Discard(); }
ReferenceCounter refcounter = new ReferenceCounter();
T stored;
};
class SimpleObject : IDisposable
{
public void Dispose() {}
}
static void Main(string[] args)
{
SmartPointer<SimpleObject> p1 =
new SmartPointer<SimpleObject>(new SimpleObject());
SmartPointer<SimpleObject> p2 =
new SmartPointer<SimpleObject>();
p2 = p1;
}
###### 2 Interface based implementation:
########################################
// Base interface for reference counted objects
interface IRefCountedObject
{
ulong AddRef();
ulong Release();
}
// Dumb implementation, only for illustration
// ! not thread safe ..... !!
class BaseRefCounted : IRefCountedObject, IDisposable
{
public ulong AddRef () { return ++l; }
public ulong Release() { if (l == 1) Dispose(); return --l; }
public void Dispose () { }
ulong l = 0;
};
// 2 Objects - first reference counted, second not
class ObjectHasRef : BaseRefCounted { }
class ObjectNoRef { }
// Dumb implementation of a SmartPointer,
// only for illustration, not tested
class SmartPointer<T> : IDisposable where T : class, IRefCountedObject
{
// Assign a new object, this should be also possible with an
// assignment operator !!! for convenience
public void Assign(T r)
{
if (r == stored) return;
if (stored != null) stored.Release();
r.AddRef(); stored = r;
}
// Releases the object and eventually calls Dispose
// if the reference is zero
public void Discard()
{
if (stored != null) stored.Release();
stored = null;
}
public void Dispose() { Discard(); }
T stored; // Points to the reference counted object
};
static void Main(string[] args)
{
ObjectNoRef no = new ObjectNoRef ();
ObjectHasRef yes = new ObjectHasRef();
SmartPointer<IRefCountedObject> p1 = new
SmartPointer<IRefCountedObject>();
SmartPointer<ObjectHasRef> p2 = new
SmartPointer<ObjectHasRef>();
p1.Assign(yes);
p2.Assign(yes);
p1.Assign(no); // Boooom compiler error
}
Please don't sue me for any errors, it was just a quick hack.
So what's missing - some automatism implemented in the CLR, which does the handling, so that I don't have to call an assign method, but can use an assignment operator and would be perfect if the compiler could also generate code which automatically disposes the reference counted object, so optimally the SmartPointer should be a stack allocated / handled object. Like value objects - but smart ;-)
--
Philip Daniels
Andre
.
- Follow-Ups:
- Re: C++/CLI is the way to go
- From: Barry Kelly
- Re: C++/CLI is the way to go
- From: Willy Denoyette [MVP]
- Re: C++/CLI is the way to go
- From: Jon Skeet [C# MVP]
- Re: C++/CLI is the way to go
- References:
- A re-announce on GC's defects
- From: Born
- C++/CLI is the way to go
- From: Born
- Re: C++/CLI is the way to go
- From: Willy Denoyette [MVP]
- Re: C++/CLI is the way to go
- From: Andre Kaufmann
- Re: C++/CLI is the way to go
- From: Philip Daniels
- Re: C++/CLI is the way to go
- From: Jon Skeet [C# MVP]
- Re: C++/CLI is the way to go
- From: Andre Kaufmann
- Re: C++/CLI is the way to go
- From: Philip Daniels
- A re-announce on GC's defects
- Prev by Date: Re: C++/CLI is the way to go
- Next by Date: Re: how do I launch my c# application from a web page?
- Previous by thread: Re: C++/CLI is the way to go
- Next by thread: Re: C++/CLI is the way to go
- Index(es):