www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Object Pointer

reply "Namespace" <rswhite4 googlemail.com> writes:
Is something like this possible?

Foo* create_ptr(Foo f) {
     assert(f !is null);
     // ...
}

Foo* fp = create_ptr(new Foo());

with "ref Foo f" of course, there is no limitation.
Jul 15 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, July 16, 2012 00:47:27 Namespace wrote:
 Is something like this possible?
 
 Foo* create_ptr(Foo f) {
      assert(f !is null);
      // ...
 }
 
 Foo* fp = create_ptr(new Foo());
 
 with "ref Foo f" of course, there is no limitation.
You cannot have pointers to classes. The language does not support it. You can have pointers to class references, and you can have pointers to structs or the built-in types, but if Foo is a class, then what you can't have a pointer to it. The closest that you can get is that I believe that you can cast class references to and from void*, and that will work, but Foo* is a pointer to a reference to Foo, not a pointer to Foo, and there's no way in the type system to represent a pointer to Foo. - Jonathan M Davis
Jul 15 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
 You cannot have pointers to classes. The language does not 
 support it. You can
 have pointers to class references, and you can have pointers to 
 structs or the
 built-in types, but if Foo is a class, then what you can't have 
 a pointer to
 it. The closest that you can get is that I believe that you can 
 cast class
 references to and from void*, and that will work, but Foo* is a 
 pointer to a
 reference to Foo, not a pointer to Foo, and there's no way in 
 the type system
 to represent a pointer to Foo.

 - Jonathan M Davis
Yes. I want a Pointer of Foo's reference, you're right. I think i have to move the reference to the heap?
Jul 16 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, July 16, 2012 09:33:42 Namespace wrote:
 Yes. I want a Pointer of Foo's reference, you're right. I think i
 have to move the reference to the heap?
If you don't want it to point to a local variable and cause problems when it goes out of scope, then yeah, though I don't know if it's possible to do that or not. Probably, but I'd have to think about it and try out a bunch of stuff to be sure. Certainly, you could stick it in a struct and have a pointer to the struct. Regardless, I would point out that you lose polymorphism if you do that. You only get polymorphism with references, not pointers. So, you don't want to try and call member functions on a class instance through a pointer. But what you really should be using is std.typecons.Rebindable. If you're operating on pointers to class references much, then you're probably doing something wrong with your design. Classes really aren't intended to be used that way. - Jonathan M Davis
Jul 16 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
I'm just experiement with D, that's all. ;)
Most of my questions here are just out of curiosity.

I have now this construct:

[code]
class smart_ptr {
private:
	A* _ptr;

public:
	this(A* ptr) {
		void* buffer = GC.malloc(A.sizeof);
		memcpy(buffer, ptr, A.sizeof);

		this._ptr = cast(A*) buffer;
	}

	~this() {
		GC.free(this._ptr);
	}

	 property
	A* Ptr() {
		return this._ptr;
	}

	alias Ptr this;
}
[/code]

And that is how i use it (ATM):

[code]
A a = new A(42);
smart_ptr sptr = new smart_ptr(&a);
sptr.echo();

a = null;

sptr.echo();
[/code]

But how can i free the memory?
Bizarrely it cannot be delete in the dtor. o.O
Strange design.
Jul 16 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, July 16, 2012 10:31:11 Namespace wrote:
 I'm just experiement with D, that's all. ;)
 Most of my questions here are just out of curiosity.
 
 I have now this construct:
 
 [code]
 class smart_ptr {
 private:
 	A* _ptr;
 
 public:
 	this(A* ptr) {
 		void* buffer = GC.malloc(A.sizeof);
 		memcpy(buffer, ptr, A.sizeof);
 
 		this._ptr = cast(A*) buffer;
 	}
 
 	~this() {
 		GC.free(this._ptr);
 	}
 
 	 property
 	A* Ptr() {
 		return this._ptr;
 	}
 
 	alias Ptr this;
 }
 [/code]
 
 And that is how i use it (ATM):
 
 [code]
 A a = new A(42);
 smart_ptr sptr = new smart_ptr(&a);
 sptr.echo();
 
 a = null;
 
 sptr.echo();
 [/code]
 
 But how can i free the memory?
 Bizarrely it cannot be delete in the dtor. o.O
 Strange design.
You can't do _anything_ which would allocate or free GC memory in a class destructor/finalizer. And even _using_ the GC heap in a class' finalizer is a _bad_ idea, because anything to which the object refers to with its member variables which is on the GC heap (be it directly or indirectly) may already have been collected by the GC (otherwise, it would have problems with circular references). But if you're allocating on the GC heap, you don't _need_ to free anything. The GC does that. Class finalizers are for managing resources _other_ than GC memory. - Jonathan M Davis
Jul 16 2012
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Only for correctness:
If i allocate memory on the GC Heap in e.g. a struct and don't 
free the memory in the DTor, then the GC free the memory 
automatically?
Jul 18 2012
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, July 18, 2012 20:37:50 Namespace wrote:
 Only for correctness:
 If i allocate memory on the GC Heap in e.g. a struct and don't
 free the memory in the DTor, then the GC free the memory
 automatically?
You don't normally _ever_ free memory from the GC heap. That's the GC's job. That's what garbage collectors _do_. There are cases where it may be valuable to explicitly free GC memory for performance reasons, but it's risky and opens yourself up to the possibility of accessing freed memory and the like. That's one of the reasons why delete is being deprecated. So, no, you don't have to free GC allocated memory in a struct's destructor. The GC takes care of it. - Jonathan M Davis
Jul 18 2012