Topic: virtual function resolution


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/07/25
Raw View
Kannan Chellappan wrote:
>
> Christopher Eltschka wrote:
>
> > Kannan Chellappan wrote:
> > >
> > > Christopher Eltschka wrote:
> > >
> > > > Siemel Naran wrote:
> > > > >
> > > > > What should the answer to following program be?
> > > > > (1) 2+1+0 = 2
> > > > > (2) (2+(1*10))*10 = 120
> > > > >
> > > > > g++ tells me (2).
> > > >
> > > > g++ is correct.
> > > >
> > > > [...]
> > > >
> > > > > When B::func(int) calls A::func(int) with the "::" operator, does it
> > > > > turn the virtual function mechanism off for just that one call, or
> > > > > forever?
> > > >
> > > > Just for that call.
> > >
> > > Infact, the virtual mechanism holds good only when you use pointers(to the
> > > base class). What is being used here is an object. remember you reference it
> > > by B().func(2)
> > >
> > > Trace of the execution is below :
> > >
> > > ANSWER = A::func(2) * 10
> > >
> > >    where A::func(2) = 2 + func(1)                 [ ie 2 + B::func(1)]
> >
> > Actually it's
> >
> >    2 + this->func(1)
> >
> > where the static type of *this is A (since it's a member function of A),
> > but the dynamic type is B (it's still the object created with B() ),
>
> I am dont fully understand that point.  How did the type of this pointer change
> to that of the base class(A) ? I call the function as B().func(2) This means that
> type of this pointer is of the derived class (B). In the derived class, i
> explicitly call the base class function func(arg). It is the same object ( B()
> )(i.e the derived class also contains the base class ), so i dont expect the type
> of this pointer to become "A" when a function of class A is called.
> Am i wrong ? Pl. let me know.

Well, the type of the this pointer is always "pointer to the class
the member function belongs to". In A::func(int), that class is A,
so the this pointer is of type A*, and therefore *this is of static
type A. Of course, the *dynamic* type of *this is B (since it's still
the B object).
This becomes obvious if you recall that the static type is determined
at compile time. Since the function A::func(int) must be callable for
every A object (and not just for the A base class part of a B object),
the this pointer cannot be of type B*.

You can easily test that by using the following program:

#include <iostream.h>

void print_type(A*) { cout << "A" << endl; }
void print_type(B*) { cout << "B" << endl; }

class A
{
  virtual void func() { print_type(this); }
};

class B: public A
{
  virtual void func() { A::func(); }
};

int main()
{
  B().func();
}

This program will output "A".
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Kannan Chellappan <chellapk@nmasd.bel.alcatel.be>
Date: 1998/07/23
Raw View
Christopher Eltschka wrote:

> Kannan Chellappan wrote:
> >
> > Christopher Eltschka wrote:
> >
> > > Siemel Naran wrote:
> > > >
> > > > What should the answer to following program be?
> > > > (1) 2+1+0 = 2
> > > > (2) (2+(1*10))*10 = 120
> > > >
> > > > g++ tells me (2).
> > >
> > > g++ is correct.
> > >
> > > [...]
> > >
> > > > When B::func(int) calls A::func(int) with the "::" operator, does it
> > > > turn the virtual function mechanism off for just that one call, or
> > > > forever?
> > >
> > > Just for that call.
> >
> > Infact, the virtual mechanism holds good only when you use pointers(to the
> > base class). What is being used here is an object. remember you reference it
> > by B().func(2)
> >
> > Trace of the execution is below :
> >
> > ANSWER = A::func(2) * 10
> >
> >    where A::func(2) = 2 + func(1)                 [ ie 2 + B::func(1)]
>
> Actually it's
>
>    2 + this->func(1)
>
> where the static type of *this is A (since it's a member function of A),
> but the dynamic type is B (it's still the object created with B() ),



I am dont fully understand that point.  How did the type of this pointer change
to that of the base class(A) ? I call the function as B().func(2) This means that
type of this pointer is of the derived class (B). In the derived class, i
explicitly call the base class function func(arg). It is the same object ( B()
)(i.e the derived class also contains the base class ), so i dont expect the type
of this pointer to become "A" when a function of class A is called.
Am i wrong ? Pl. let me know.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/07/20
Raw View
Kannan Chellappan wrote:
>
> Christopher Eltschka wrote:
>
> > Siemel Naran wrote:
> > >
> > > What should the answer to following program be?
> > > (1) 2+1+0 = 2
> > > (2) (2+(1*10))*10 = 120
> > >
> > > g++ tells me (2).
> >
> > g++ is correct.
> >
> > [...]
> >
> > > When B::func(int) calls A::func(int) with the "::" operator, does it
> > > turn the virtual function mechanism off for just that one call, or
> > > forever?
> >
> > Just for that call.
>
> Infact, the virtual mechanism holds good only when you use pointers(to the
> base class). What is being used here is an object. remember you reference it
> by B().func(2)
>
> Trace of the execution is below :
>
> ANSWER = A::func(2) * 10
>
>    where A::func(2) = 2 + func(1)                 [ ie 2 + B::func(1)]

Actually it's

   2 + this->func(1)

where the static type of *this is A (since it's a member function of A),
but the dynamic type is B (it's still the object created with B() ),
so the virtual call mechanism resolves this to B::func(1).
Just to be explicit (and to show that there's indeed a call by pointer
involved, namely a call by this-pointer inside A::func).

>    where B::func(1) = A::func(1) * 10
>    finally A::func(1) = 1
>
>   substituting back, we get    (2 + (1 * 10) )  * 10 = 120


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Kannan Chellappan <chellapk@nmasd.bel.alcatel.be>
Date: 1998/07/13
Raw View
Christopher Eltschka wrote:

> Siemel Naran wrote:
> >
> > What should the answer to following program be?
> > (1) 2+1+0 = 2
> > (2) (2+(1*10))*10 = 120
> >
> > g++ tells me (2).
>
> g++ is correct.
>
> [...]
>
> > When B::func(int) calls A::func(int) with the "::" operator, does it
> > turn the virtual function mechanism off for just that one call, or
> > forever?
>
> Just for that call.

Infact, the virtual mechanism holds good only when you use pointers(to the
base class). What is being used here is an object. remember you reference it
by B().func(2)

Trace of the execution is below :

ANSWER = A::func(2) * 10

   where A::func(2) = 2 + func(1)                 [ ie 2 + B::func(1)]
   where B::func(1) = A::func(1) * 10
   finally A::func(1) = 1

  substituting back, we get    (2 + (1 * 10) )  * 10 = 120

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/07/10
Raw View
Siemel Naran wrote:
>
> What should the answer to following program be?
> (1) 2+1+0 = 2
> (2) (2+(1*10))*10 = 120
>
> g++ tells me (2).

g++ is correct.

[...]

> When B::func(int) calls A::func(int) with the "::" operator, does it
> turn the virtual function mechanism off for just that one call, or
> forever?

Just for that call.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1998/06/29
Raw View

What should the answer to following program be?
(1) 2+1+0 = 2
(2) (2+(1*10))*10 = 120

g++ tells me (2).



#include <iomanip.h>

struct A
{
     virtual int func(int i) const
     {
          cout << "A::func(int=" << i << ")\n";
          return i ? i+func(i-1) : 0;
     }
};

struct B : public A
{
     int func(int i) const
     {
          cout << "B::func(int=" << i << ")\n";
          return A::func(i) * 10;
     }
};

int main(int argc, char const *argv[])
{
     cout << "ANSWER = " << B().func(2) << endl;
}




When B::func(int) calls A::func(int) with the "::" operator, does it
turn the virtual function mechanism off for just that one call, or
forever?


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]