Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

virtual functions 1

Status
Not open for further replies.

CodingNovice

Programmer
Dec 30, 2003
108
GB
On the whole I understand virtual functions but there is one thing I cant fathom....

virtuality.h

#include <iostream>
using std::cout;
using std::endl;

class A
{
public:
virtual ~A() {}
virtual void f() { cout << &quot;A::f()&quot; << endl; }
};

class B : public A
{
public:
virtual ~B() {}
virtual void f() { cout << &quot;B::f()&quot; << endl; }
};

class C : public B
{
public:
virtual ~C() {}
virtual void f() { cout << &quot;C::f()&quot; << endl; }
};

class D : public C
{
public:
virtual ~D() {}
virtual void f() { cout << &quot;D::f()&quot; << endl; }
};

virtuality.cpp

#include &quot;virtuality.h&quot;

int main()
{
A* array[4] = { new C, new B, new A, new D };
B* array2[3] = { new B, new D, new C };
for( int i=0;i<4;++i)
{
array->f();
delete array;
}
for ( int i=0;i<3;++i)
{
(*array2).f();
delete array2;
}
std::cin.get();
return 0;
}

Now here in the first loop I call a virtual function through a pointer so dispatch is virtual. In the second loop I call a virtual function through an object. So shouldn't the second loop call B::f() 3 times? However it doesnt. It seems that that also is virtually dispatched. Thinking in c++ (my text book) says that virtual functions called through objects are early bound. So why does my second loop late bind?
I would like to be 100% sure in my head that when I use virtual functions I know exactly which function will be called. My compiler is telling me that im wrong here but i dont understand why.

I have an array with 3 B* in it that point to various derivatives of B. Surely when I dereference a B*, to get an object, I should get a B no matter what the dynamic type of the object really is. So calling f() through an object of type B should call B::f(). So why is this not happening? Where am I going wrong in my understanding?
 
You made some typos when you fixed the problems from your other post (and I don't think it was necessary to post to both forums). But based on what I assume your code is supposed to be, you have:
Code:
    (*array2[i]).f();
This is equivalent to:
Code:
    B* ptr = array2[i];
    (*ptr).f();
That is basically equivalent to:
Code:
    B* ptr = array2[i];
    ptr->f();
which is why it acts polymorphicly. If you really want to check an object, you must actually use that object. One way to see this is to make a copy like this:
Code:
    for ( int i=0;i<3;++i)
    {
        B obj = *array2[i];
        obj.f();
        delete array2[i];
    }
In that case, even though the source of the copy was of the derived type, the object itself is of the base type (B), so B's function is called.

I guess the point is that
Code:
(*ptr).f()
is evaluated in the same way as
Code:
ptr->f()
, even though it looks like you are dereferencing.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top