www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why does this extremely simple operation not work?

reply "William" <squidkidsignup gmail.com> writes:
This is an absurdly noobish question, but here goes.  I'm 
learning D (I'm already reasonably comfortable with C and 
Objective-C, so compiled languages are not new to me), and I 
can't figure out why this super simple operation doesn't work.

I have a parent and a child class, and while implicit casting 
from child to parent works (function which takes parent will 
accept instance of child), it does not work with pointers (and 
yes, I understand that because objects are reference types a 
MyObject* is really a pointer to a pointer since a MyObject is a 
pointer).  A function that takes a Parent* as an argument will 
not accept &myChild in its place without an explicit 
cast(Parent*)&myChild.

I feel like there's some fundamental property of the D 
implementation that I'm not getting.  I was under the impression 
an subtype's instance could *always always always* be put in 
place of an instance of the super type.  Why are pointers an 
exception?

class Parent {}
class Child : Parent {}

void myFunc(Parent* obj) {
	writeln("got ", obj);
}

void main() {
	Child myChild = new Child();
	myFunc(&myChild);
}

referenceTest.d(11): Error: function referenceTest.myFunc 
(Parent* obj) is not callable using argument types (Child*)
referenceTest.d(11): Error: cannot implicitly convert expression 
(& myChild) of type Child* to Parent*
Feb 12 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 12 February 2013 at 16:58:24 UTC, William wrote:
 This is an absurdly noobish question, but here goes.  I'm 
 learning D (I'm already reasonably comfortable with C and 
 Objective-C, so compiled languages are not new to me), and I 
 can't figure out why this super simple operation doesn't work.

 I have a parent and a child class, and while implicit casting 
 from child to parent works (function which takes parent will 
 accept instance of child), it does not work with pointers (and 
 yes, I understand that because objects are reference types a 
 MyObject* is really a pointer to a pointer since a MyObject is 
 a pointer).  A function that takes a Parent* as an argument 
 will not accept &myChild in its place without an explicit 
 cast(Parent*)&myChild.

 I feel like there's some fundamental property of the D 
 implementation that I'm not getting.  I was under the 
 impression an subtype's instance could *always always always* 
 be put in place of an instance of the super type.  Why are 
 pointers an exception?

 class Parent {}
 class Child : Parent {}

 void myFunc(Parent* obj) {
 	writeln("got ", obj);
 }

 void main() {
 	Child myChild = new Child();
 	myFunc(&myChild);
 }

 referenceTest.d(11): Error: function referenceTest.myFunc 
 (Parent* obj) is not callable using argument types (Child*)
 referenceTest.d(11): Error: cannot implicitly convert 
 expression (& myChild) of type Child* to Parent*

You'd get the same behavior problem in C++. Where you can't pass a "Child**" when asking for a "Parent**". Long story short, if you could, you'd be able to place a parent instance inside a child instance, and mess everything up: void myFunc(Parent* obj) { static Parent par; if(!par) par = new Parent(); obj = &par; } void main() { Child myChild = new Child(); myFunc(&myChild); //Here, myChild is a reference to a Parent => Type system broken }
Feb 12 2013
prev sibling next sibling parent d coder <dlang.coder gmail.com> writes:
In D, class objects are implicitly pointers. So try the following code.

class Parent {}
class Child : Parent {}

void myFunc(Parent obj) {
  import std.stdio;
  writeln("got ", obj);
}

void main() {
  Child myChild = new Child();
  myFunc(myChild);
}
Feb 12 2013
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, February 12, 2013 18:04:18 monarch_dodra wrote:
 You'd get the same behavior problem in C++. Where you can't pass
 a "Child**" when asking for a "Parent**". Long story short, if
 you could, you'd be able to place a parent instance inside a
 child instance, and mess everything up:
 
 void myFunc(Parent* obj)
 {
 static Parent par;
 if(!par) par = new Parent();
 obj = &par;
 }
 void main() {
 Child myChild = new Child();
 myFunc(&myChild);
 //Here, myChild is a reference to a Parent => Type system broken
 }

Yeah. It's good to keep in mind that whenever you see a class referred to as a type, it's really referring to a reference to a class object, _not_ the class object itself, which is why &obj doesn't point to the class object but to its reference, and the reference doens't have a parent or child relationship with any classes - just the class itself has that. - Jonathan M Davis
Feb 12 2013
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/12/2013 08:58 AM, William wrote:

 I'm learning D

There is also the D.learn newsgroup. Ali
Feb 13 2013