Thread overview
indirect covariance
Aug 26, 2003
DeadCow
Aug 26, 2003
DeadCow
Aug 27, 2003
Antti Sykäri
Aug 27, 2003
Antti Sykäri
Aug 27, 2003
DeadCow
August 26, 2003
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




August 26, 2003
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


August 27, 2003
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

August 27, 2003
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

August 27, 2003
"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