-
November 2nd, 2009, 06:35 AM
#1
Covariant return types and virtual function
As I understand, below code wont compile due to definition of covariant return type (it has to be reference or pointer).
But If I just remove 'virtual' keyword then it compiles(and runs).
Any thoughts why it compiles even when the return type is not pointer or reference(when base fun is non-virtual)?
And why it fails when base fun is virtual?
Thanks for your time.
-Sachin
#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;
class A
{
public:
virtual A fun()
{
cout<<"A fun\n";
return *this;
}
};
class B: public A
{
public:
B fun()
{
cout<<"B fun"<<endl;
return *this;
}
};
int main()
{
B obj;
A *ptr = &obj;
obj.fun();
ptr->fun();
getch();
return 0;
}
-
November 2nd, 2009, 08:13 AM
#2
Re: Covariant return types and virtual function
Without the "virtual" keyword A::fun and B::fun don't have anything to do with each other. They are two separate functions who just happen to have the same name. The compiler simply does not care about them having different return types.
If the functions are virtual, the return type has to be a pointer or reference to avoid truncation of the object to take place. In your example, B::fun() would return a B object which would then immediately be converted to an A object and all information that would make it a B object would be lost. In term, it does not make sense for the function to return a B object in the first place.
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
-
November 2nd, 2009, 08:45 AM
#3
Re: Covariant return types and virtual function
Thanks for the reply. That explains me correctly.
So I guess we can say, the child class is hiding the fun in parent class, right?
Regarding the 'truncation' - whats happening in below code? Is there any flaw?
I am getting expected output - is it just by chance?
class A
{
public:
A fun()
{
cout<<"A fun\n";
return *this;
}
};
class B: public A
{
public:
B fun()
{
cout<<"B fun"<<endl;
return *this;
}
void test_fun()
{
cout<<"B's Test fun"<<endl;
}
};
int main()
{
B obj;
A *ptr = &obj;
B* ptr1 = (B *)&(ptr->fun());
ptr1->test_fun();
getch();
return 0;
}
Regards,
-Sachin
-
November 2nd, 2009, 09:13 AM
#4
Re: Covariant return types and virtual function
Originally Posted by sachhi99
Thanks for the reply. That explains me correctly.
So I guess we can say, the child class is hiding the fun in parent class, right?
Regarding the 'truncation' - whats happening in below code? Is there any flaw?
I am getting expected output - is it just by chance?
class A
{
public:
A fun()
{
cout<<"A fun\n";
return *this;
}
};
class B: public A
{
public:
B fun()
{
cout<<"B fun"<<endl;
return *this;
}
void test_fun()
{
cout<<"B's Test fun"<<endl;
}
};
int main()
{
B obj;
A *ptr = &obj;
B* ptr1 = (B *)&(ptr->fun());
ptr1->test_fun();
getch();
return 0;
}
Regards,
-Sachin
Depends what you mean by "expected". In my opinion, you aren't getting expected output.
Code:
int main()
{
B obj;
A *ptr = &obj;
ptr->fun();
}
This says "A fun" when the pointer is clearly pointing to a B object. Is this the behavior you want?
In your case, there is no slicing, because your classes are not virtual, but you have a bigger problem of reference to temporary...
-
November 2nd, 2009, 10:21 AM
#5
Re: Covariant return types and virtual function
Please start using code tags for your code. Read the FAQ!
Code:
B* ptr1 = (B *)&(ptr->fun());
The behaviour of your program after this line is undefined. ptr->fun() returns an A object. As not every A is a B, assuming that it is, will result in undefined behaviour.
In your case, this will work as your classes don't have data members. Even if they did, there are chances that it will work as you expect (this is part of "undefined behaviour"). But you will never know if it works all the time or if you run it on a different platform or compile it with a different compiler.
Last edited by treuss; November 2nd, 2009 at 10:23 AM.
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf
Premature optimization is the root of all evil --Donald E. Knuth
Please read Information on posting before posting, especially the info on using [code] tags.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|