November 28, 2002
"Laurentiu Pancescu" <plaur@crosswinds.net> wrote in message news:as5qg9$ean$1@digitaldaemon.com...
> This means that D uses only late binding, just like Java, right? Otherwise, this wouldn't affect non-virtual methods...

That's correct. It isn't perfect, just better. Also, the gc won't delete things that still have references to them, this technique only applies when objects are manually deleted.

I've switched all my own new code, even my C++ code, to using GC. It saves a lot of programming time <g>.


November 29, 2002
In article <as36h0$m0j$1@digitaldaemon.com>, Laurentiu Pancescu says...
>
>One solution:
>
>class X
>{
>   bool deleted_;
>public:
>   X() : deleted_(false) {}
>   virtual ~X() { deleted_ = true; }
>   bool valid() {
>     if (deleted_) throw WhateverGoodNameYouCanThinkOf();
>     return true; }
>};

mm.. this seems very dangerous. Since any attempt to access the Valid() member through an invalid pointer is undefined. It might not work at all, it might work until you add some more code to the module, or get a kernel patch, or just about anything.. it might work for 10 minutes, 2 days, or even three years.. and then bang.

>Second solution:

This is a very good solution for windows platform.

>Third solution, probably best:
>
>Rethink your object lifetime design.

Yes, rethink. Perhaps use surrogate class with associated resource / usecnt object that points to an actual object (the X class in the original poster's example). See the first few chapters of "Ruminitions on C++" for a description of Handles. Also, I think latest edition of Stroustrup's "The C++ Programming Language", talks about resource handling. In any case, with Handles, you can add a destroy method to the Handle class that destroys the object pointed to by the resource object, and marks the resource object as invalid. Handle member conversion operators to reference or pointer of the real class (again the X class) can check the validity of the resource, and throw exceptions to your try block. I tend to use a Handle template and resource allocate through it. This is also effective for use in STL containers that expect cc'tor on insertion (except for any containers like vector with its nasty unitialized_copy). Using a handle, an STL container like list can be tied to the object and when the container goes out of scope, so do the objects. Here's a brief example using the original poster's example. If you find a bug, let me know so I can fix my Handle template!

#include <iostream>

struct X { };

struct X_Resource {

friend struct X_Handle;

X_Resource(X* x) : usecnt(1), obj(x) { }

~X_Resource() { delete obj; }

X* obj;

int usecnt;
};

struct X_Handle {

X_Resource* r;

X_Handle(X* x)
{
r = new X_Resource(x);
}

X_Handle(const X_Handle& h)
{
r = h.r;
r->usecnt++;
}

X_Handle& operator=(X_Handle& h)
{
if (this != &h) {
r->usecnt--;
if (r->usecnt == 0)
delete r;
r = h.r;
r->usecnt++;
}
return *this;
}

operator X&() throw (int)
{
X* obj = r->obj;
if (obj == 0)
throw int(1);
return *obj;
}

~X_Handle()
{
r->usecnt--;
if (r->usecnt == 0)
delete r;
}

void destroy()
{
X* obj = r->obj;
delete obj;
r->obj = 0;
}
};

main()
{
X_Handle x(new X);
x.destroy();
try{
X& test = x;
cout<<"i have reached here(Problem)";
}
catch(...){
cout<<"Trying to access invalid object";
}
}

Richard


1 2
Next ›   Last »