Help me understand Overriding a virtual function

C

CoolPint

I read that the return type has to be exactly same for a virtual
function to be overriden. While testing something, I discovered
something I cannot understand.
I cannot understand why the code below compiles.

I see that it won't compile if I have "virtual char & vtest() { }" in
Base class
and have "virtual const char & vtest() { }" in Derived class.

But it compiles if I have "virtual const char & vtest() { }" in Base
class and have "virtual char & vtest() { }" in derived class.
Why? What's going on?

Similarly, operator*() functions compiles as written, but always
returns const int & even I assign derived object to Base reference.
Please have a look at comments on function fun() to see what I mean.

Can anyone kindly explain why it compiles yet won't do dynamic
binding?
Thanks always (especially to you, Victor B.)

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

class CPtr {
public:
CPtr(int * a):ptr(a) { };
virtual const int & operator*() const
{
return *ptr;
}
virtual const char & vtest() { }
protected:
int * ptr;
};

class Ptr: public CPtr {
public:
Ptr(int * a):CPtr(a) { };
virtual int & operator*() const
{
return *ptr;
}
virtual char & ttest() { }
};

void fun(CPtr & p)
{
// I was hoping this would work since a Ptr object is passed and
// dynamically it would bind to virtual int & operator*() const
// But it binds to virtual const int & operator*() const at compile
time
// Why?

// cout << ++(*p) << endl;
}

int main()
{
int i = 10;
Ptr pt(&i);
cout << ++(*pt) << endl;
fun(pt);

return 0;
}
 
N

Nick Hounsome

CoolPint said:
I read that the return type has to be exactly same for a virtual
function to be overriden. While testing something, I discovered
something I cannot understand.
I cannot understand why the code below compiles.

I see that it won't compile if I have "virtual char & vtest() { }" in
Base class
and have "virtual const char & vtest() { }" in Derived class.

Because if it did you could violate const correctness.
But it compiles if I have "virtual const char & vtest() { }" in Base
class and have "virtual char & vtest() { }" in derived class.
Why? What's going on?

Because with this you can't:
A CPtr will return you a cont reference whether or not it is actually a Ptr.
Similarly, operator*() functions compiles as written, but always
returns const int & even I assign derived object to Base reference.
Please have a look at comments on function fun() to see what I mean.

Can anyone kindly explain why it compiles yet won't do dynamic
binding?
Thanks always (especially to you, Victor B.)

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

class CPtr {
public:
CPtr(int * a):ptr(a) { };

This is the start of your misconceptions:
If CPtr is a pointer to a const int then why doesn't it take one ine the
constructor?
Your CPtr cannot actually point to a constant integer!
If you change to CPtr(const int*) the problems that you will then have with
Ptr(int*) should show you
why your design is flawed and why C++ works the way it does.
virtual const int & operator*() const
{
return *ptr;
}
virtual const char & vtest() { }

returns what?
protected:
int * ptr;
};

class Ptr: public CPtr {

inheritance is not appropriate here.
You are saying "Every Ptr IS-A CPtr"
or "every pointer is a pointer to constant except that you can change it!"
This is obviously nonsensical.
public:
Ptr(int * a):CPtr(a) { };

If you had CPtr(const int*) you would not now be able to initialize it with
a.
virtual int & operator*() const
{
return *ptr;
}
virtual char & ttest() { }
};

void fun(CPtr & p)
{
// I was hoping this would work since a Ptr object is passed and
// dynamically it would bind to virtual int & operator*() const
// But it binds to virtual const int & operator*() const at compile
time

No it doesn't - it binds to virtual int& operator*() (look at the asembler)
BUT the the return type is treated as const int& because that is what it is
in CPtr.

C++ uses dynamic function calls but static type checking.
Or to put it another way virtual function calls select functions at runtime
NOT types.
 
C

CoolPint

No it doesn't - it binds to virtual int& operator*() (look at the asembler)
BUT the the return type is treated as const int& because that is what it is
in CPtr.

C++ uses dynamic function calls but static type checking.
Or to put it another way virtual function calls select functions at runtime
NOT types.

Does that mean return types of virtual functions do not take part in
the resolving of dynamic binding?

Thank you for your comments. The coding was made just to illustrate
the points I am trying to ask in simple way without considering the
design. What I really want to find out is the feature of the langauge
and how it works and you kind of answered above there but it's not
clear to me yet. Could you kindly elaborate a bit more?

Books say the return type has to be exactly same when a virtual
function is overriden but why doesn't compiler complain in the
following case:

Base member's return type : virtual const T &
Derived member's return type : virtual T &

They look different types to me but compiler doesn't complain. But
compiler complains when the situation is reversed though.

Does this mean I have successfully overridden the function for dynamic
binding to work? If then, why calling the member function through base
reference would return the base class member's return type?

Thank you for your patience.
 
R

Ron Natalie

CoolPint said:
Does that mean return types of virtual functions do not take part in
the resolving of dynamic binding?

Correct. The important issue is name and parameter list. However,
the return types of overriding functions are required to be same or one
of the legal related types.
Books say the return type has to be exactly same when a virtual
function is overriden but why doesn't compiler complain in the
following case:

Those books are wrong. The rule is relaxed in the case when:
1. Both returns are pointers or references to classes
2. The type of the base class function return is an unambiguous accessible base class
of the return of the derived class function
3. The CV-qualification is the same for the pointers, and the same or less qualfifed for
the pointed/referred to derived object
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top