www.digitalmars.com         C & C++   DMDScript  

D - indirect covariance

reply "DeadCow" <deadcow-remove-this free.fr> writes:
Hello,

class Visitor {
  void visit( Foo f ) { printf("Foo"); }
  void visit( Foo2 f ) { printf("Foo2"); }
}

class Foo {
  void accept( Visistor v ) { v.visit(this); }
}

class Foo2 : Foo {}

void main() {
  Visitor v = new Visitor();
  Foo2 f2 = new Foo2();

  v.visit( f2 );  // output is "Foo2"
  f2.accept( v ); // output is "Foo" ...
}

Is it a bug ?

-- Nicolas Repiquet
Aug 26 2003
next sibling parent reply "DeadCow" <deadcow-remove-this free.fr> writes:
class A {}
class B : A {}
class C : B {}

class Z {
  void foo( A a ) { printf("A");}
  void foo( B b ) { printf("B");}
  void foo( C c ) { printf("C");}
}

void main() {
  Z z = new Z();
  A a = (A)new C();
  z.foo( a );
}


Output: "A"

There is no dynamic dispatch ?

-- Nicolas Repiquet
Aug 26 2003
parent Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <big6gm$2hkj$1 digitaldaemon.com>, DeadCow wrote:
 class A {}
 class B : A {}
 class C : B {}
 
 class Z {
   void foo( A a ) { printf("A");}
   void foo( B b ) { printf("B");}
   void foo( C c ) { printf("C");}
 }
 
 void main() {
   Z z = new Z();
   A a = (A)new C();
   z.foo( a );
 }
 
 
 Output: "A"
 
 There is no dynamic dispatch ?

Dynamic dispatch works only on the target type, i.e. the type of "this" inside the method. Consequently, you'd have to make foo() a method of A and call it on an object of type A: class A { void foo() { printf("A\n"); } } class B { void foo() { printf("B\n"); } } class C { void foo() { printf("C\n"); } } void main() { A a = (A) new C(); a.foo(); } Output: "C" -Antti
Aug 27 2003
prev sibling parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bifjdm$1k7d$1 digitaldaemon.com>, DeadCow wrote:

The code was more or less like:

class Visitor {
  void visit( Foo f ) { printf("Foo\n"); }
  void visit( Foo2 f ) { printf("Foo2\n"); }
}

class Foo {
  void accept( Visitor v ) { v.visit(this); }
}

class Foo2 : Foo {}

void main() {
  Visitor v = new Visitor();
  Foo2 f2 = new Foo2();

  v.visit( f2 );  // output is "Foo2"
  f2.accept( v ); // output is "Foo" ...
}

 Is it a bug ?

No; it's simply a result of how the code is compiled. The signature of the method that is called is determined at compile-time, while the actual method might be picked at run-time. v.visit(f2) calls Visitor's visit(Foo2) method directly. However, f2.accept(v) calls Foo.accept(Visitor v). When that method is being compiled, "this" is of type Foo. If you want the behavior that f2.accept(v) should print Foo2, you'd have to make Foo2 override accept(Visitor): class Foo2 : Foo { void accept( Visitor v ) { v.visit(this); } } -Antti
Aug 27 2003
parent "DeadCow" <deadcow-remove-this free.fr> writes:
"Antti Sykäri" <jsykari gamma.hut.fi> a écrit dans le message news:
slrnbkqg70.s51.jsykari pulu.hut.fi...

 If you want the behavior that f2.accept(v) should print Foo2, you'd have
 to make Foo2 override accept(Visitor):

 class Foo2 : Foo {
   void accept( Visitor v ) { v.visit(this); }
 }

It's a quite acceptable solution. Thanks ! -- Nicolas Repiquet
Aug 27 2003