digitalmars.D - casting class pointer
- Jesse Phillips (21/21) Nov 18 2010 I usually avoid using pointers and classes together (actually I don't us...
- Jonathan M Davis (7/45) Nov 18 2010 Just dereference the pointer. I believe that in effect you have a pointe...
- Jesse Phillips (3/6) Nov 18 2010 The question wasn't exactly about how to get a reference to the class. T...
- Simen kjaeraas (23/31) Nov 19 2010 Not surprising. hi is pointing to a reference (pointer) to a B instance,
I usually avoid using pointers and classes together (actually I don't use pointers very much). But using 'in' on an associative array provides a pointer. In any case, I ended up casting the pointer to the class type. (The simplified example isn't showing the behavior). The results were not good. I'm not sure exactly what happened but the code is something like this: import std.stdio; class A { string label; /* ... */ } class B : A { B[string] all; string[] stuff; } void main() { auto b = new B(); b.label = "Fish";//Filler b.stuff ~= "Cool huh";//Filler b.all["hello"] = b;//Filler auto hi = "hello" in b.all; auto foo = cast(B) hi; foreach(s; foo.stuff) { writeln(s); } } The result was that b.label wasn't the same, and printing out stuff resulted in a bunch of garbage. The questions I have are, should casting a class pointer to a class change its behavior so it just gives you the class? Is is there a use case for the current behavior? And should I bother working to reproduce this? Maybe to! could be made to handle this, and upcasting?
Nov 18 2010
On Thursday, November 18, 2010 14:20:01 Jesse Phillips wrote:I usually avoid using pointers and classes together (actually I don't use pointers very much). But using 'in' on an associative array provides a pointer. In any case, I ended up casting the pointer to the class type. (The simplified example isn't showing the behavior). The results were not good. I'm not sure exactly what happened but the code is something like this: import std.stdio; class A { string label; /* ... */ } class B : A { B[string] all; string[] stuff; } void main() { auto b = new B(); b.label = "Fish";//Filler b.stuff ~= "Cool huh";//Filler b.all["hello"] = b;//Filler auto hi = "hello" in b.all; auto foo = cast(B) hi; foreach(s; foo.stuff) { writeln(s); } } The result was that b.label wasn't the same, and printing out stuff resulted in a bunch of garbage. The questions I have are, should casting a class pointer to a class change its behavior so it just gives you the class? Is is there a use case for the current behavior? And should I bother working to reproduce this? Maybe to! could be made to handle this, and upcasting?Just dereference the pointer. I believe that in effect you have a pointer to a reference, not a pointer to an Object. Regardless of what it does internally though, the way to get at the object is to dereference it. If you had auto foo = *hi; then foo would be a reference to B, which is what you were trying to get. - Jonathan M Davis
Nov 18 2010
Jonathan M Davis Wrote:Just dereference the pointer. I believe that in effect you have a pointer to a reference, not a pointer to an Object. Regardless of what it does internally though, the way to get at the object is to dereference it. If you hadThe question wasn't exactly about how to get a reference to the class. The code has been evolving over time, and the cast was originally there to convert a reference of type A to type B. As I've been changing it things have become pointers and most importantly their actual type. (I've actually removed most pointers now). I just thought having cast basically do a deference/conversion wouldn't be a bad thing when casting to a class. I realize cast is supposed to be a fast operation, but if it could do the right thing too, that would be nice. Since it is there to break the type system I can't exactly ask for it to throw an Error.
Nov 18 2010
Jesse Phillips <jessekphillips+D gmail.com> wrote:auto hi = "hello" in b.all; auto foo = cast(B) hi;The result was that b.label wasn't the same, and printing out stuff resulted in a bunch of garbage.Not surprising. hi is pointing to a reference (pointer) to a B instance, not a proper B, and certainly not the one you hope for. Thus, random garbage from the memory surrounding the reference is outputted.The questions I have are, should casting a class pointer to a class change its behavior so it just gives you the class? Is is there a use case for the current behavior? And should I bother working to reproduce this?The idea behind the in operator for AAs is that it indicate whether there was something at the specified index, by returning null if there wasn't. IOW, 'a in AA' does not return a class reference, and shouldn't. You may have reasons to put nulls in your AA, in which case the returned B* may be non-null, while *hi is null. I have not thought of a good use case for this, though. However, the main reason I see is symmetry. Having to explain that for T[U] t, 'a in t' returns a T* is ok. Having to explain that this simple rule breaks when T is a class, is not good. Last, a cast is a message to the compiler of "Trust me, I know what I'm doing". That could mean that your B* is actually a B (a reference), that somehow ended up being a B*. In such a case, the only reasonable thing to do is interpreting the bits as a B instead of a B*. What you should do in the above code is auto foo = *hi; tl;dr: making the casting of class reference pointers to class references do the shortcut of interpreting the pointer as a reference is asymmetric and limits the language. -- Simen
Nov 19 2010