Virtual Funtion Questions

G

garyolsen

Case 1:
==============

class MyClass
{
public:
virtual void MyVirt();
};

class MyChildClass : public MyClass
{
public:
void MyVirt();
};

If MyClass contains a virtual function which will be overridden by it
children classes:

MyChildClass *MChildC = new MyChildClass();
MyClass* ptr = MChildC;
ptr->MyVirt();//MyChildClass::MyVirt() called

Otherwise, the overriding function, MyVirt(), in MyChildClass will not be
executed?

Everything fine. Please read on...


Case 2:
=============

The same two classes as in Case 1.

MyChildClass MCC;
MyClass* ptr = &MCC;
ptr->MyVirt();

Will the staement, ptr->MyVirt(), actually call MyChildClass::MyVirt()?
Is this a general practice of polymorphism in C++ like in Case 1?

Now, this leads me to another question:

Why such a "Pointer"/"Reference" requirement needed to cause a late binding?


Case 3:
==============

Now we make some changes for the above two classes:

class MyClass
{
public:
void MyNonVirt() { MyVirt(); }

private:
virtual void MyVirt();
};

class MyChildClass : public MyClass
{
private:
void MyVirt();
};

Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.

First, is this a good design at all?

How should I do to make sue that MyChildClass::MyVirt() is called at
runtime?


Thanks!
 
R

Ron Natalie

garyolsen said:
Why such a "Pointer"/"Reference" requirement needed to cause a late binding?

The only way you can get to a an object whose dynamic type is different from
the static type is to use (at least implcitly) a pointer or reference.

MCC.MyVirt(); // no brainer, MCC is of type MyChildClass
ptr->MyVirt(); // must figure out dymaic type of *ptr at runtime
Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.

Protection doesn't have any bearing on virtual. You can't call MyVirt() from
outside MyClass if it's private (makes no different if virtual or not)>
How should I do to make sue that MyChildClass::MyVirt() is called at

It will be called if you call MyNonVirt() in the context of a MyChildClass object.


The way function calling works is like this:

1. First for the static type of the call, the name is looked up. If you call through
a pointer of type MyClass, then it finds MyCLass::MyNonFirst.
2. Possible overloads are checked (you only have the one).
3. Access is checked (OK, public).
4. If virtual, the final overrider is substituted (it's not).

Ok, now you're executing MyNonVirt. You go through the process again:

1. Lookup Name: Find MyClass::MyVirt
2. Check overloads (only one).
3. Check access (fine, private but being called from within class)
4. If virtual, substitute final overrider (yes, it's virtual, object is of type MyChildClass so My ChildClass::MyVirt is run).
 
V

Victor Bazarov

garyolsen said:
Case 1:
==============

class MyClass
{
public:
virtual void MyVirt();
};

class MyChildClass : public MyClass
{
public:
void MyVirt();
};

If MyClass contains a virtual function which will be overridden by it
children classes:

MyChildClass *MChildC = new MyChildClass();
MyClass* ptr = MChildC;
ptr->MyVirt();//MyChildClass::MyVirt() called

Otherwise, the overriding function, MyVirt(), in MyChildClass will not be
executed?

Yes. If the function is not virtual, there is no "overriding" of it,
the MyChildClass' function with the same name would _hide_ the MyClass'
one.
Everything fine. Please read on...


Case 2:
=============

The same two classes as in Case 1.

MyChildClass MCC;
MyClass* ptr = &MCC;
ptr->MyVirt();

Will the staement, ptr->MyVirt(), actually call MyChildClass::MyVirt()?

Of course. What's the difference with the above, really? That
the object was created in freestore instead of automatically? It
makes no difference.
Is this a general practice of polymorphism in C++ like in Case 1?
Similar.

Now, this leads me to another question:

Why such a "Pointer"/"Reference" requirement needed to cause a late
binding?

Because without it (by value) the _slicing_ occurs, and there is no
original object left.
Case 3:
==============

Now we make some changes for the above two classes:

class MyClass
{
public:
void MyNonVirt() { MyVirt(); }

private:
virtual void MyVirt();
};

class MyChildClass : public MyClass
{
private:
void MyVirt();
};

Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.

First, is this a good design at all?

It's _a_ design. There has to be a purpose to it. If such design
exists, there must have been a purpose. Don't ask us to guess it.
How should I do to make sue that MyChildClass::MyVirt() is called at
runtime?

The same way. If your pointer to MyClass is a pointer to a _subobject_
of an object of MyChildClass, then calling MyNonVirt for it will cause
the internal call to MyVirt to be dispatched _dynamically_. So, no
special action necessary.

Victor
 
J

jeffc

garyolsen said:
Case 2:
=============

The same two classes as in Case 1.

MyChildClass MCC;
MyClass* ptr = &MCC;
ptr->MyVirt();

Will the staement, ptr->MyVirt(), actually call MyChildClass::MyVirt()?
Is this a general practice of polymorphism in C++ like in Case 1?

Yes, it might not be done exactly that way - it might be a parameter on a
function call, but the idea is the same.
Why such a "Pointer"/"Reference" requirement needed to cause a late
binding?

Because there's isn't an alternative. How else would you cause late
binding?
Case 3:
==============

Now we make some changes for the above two classes:

class MyClass
{
public:
void MyNonVirt() { MyVirt(); }

private:
virtual void MyVirt();
};

class MyChildClass : public MyClass
{
private:
void MyVirt();
};

Note that MyNonVirt() calls MyVirt() and MyVirt() is private member now.

First, is this a good design at all?

It looks OK to me, depending on what you need to accomplish.
How should I do to make sue that MyChildClass::MyVirt() is called at
runtime?

As you have it written, it will be - assuming an object of type MyChildClass
such as
MyClass* pClass = new MyChildClass;
pClass->MyNonVirt();
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top