|
From: Ioannis V. <no...@ya...> - 2001-10-21 10:20:18
|
Jason, i strongly disagree with you. :) Each object has its *own* member
functions and no external function is passed to them in anyway. That's
why the cost of calling a member function is smaller than the cost of
calling an external function. For accuracy, the compiler should behave
as if this happens. :) Compiler can optimize its way as it likes as far
as it follows this behavior. In our case C class is derived from A, so a
C object contains a A object. Also we have public inheritance which
means that all methods of A are accessible within C if not overided.=20
A C object has bigger size than a A object. Here we have a A object not
a C object. If we could do these kinds of things we could create base
class objects cast them to their derived types and have derived objects
doing the same things having smaller size (=3Dmiracle).
In our case my theory is that this happens: The compiler trying to
produce even smaller size than it would in normal situation, creates
common instances of member functions. Here it gets confused by the
casting and a mess is created.
=20
Proof that this is a compiler defect:
=20
#include <iostream>
=20
class A
{
public:
char a;
void test() { a=3D'A'; }
};
=20
class C: public A
{
public:
char b;
void test() { a=3D'C'; b=3D'D'; }
};
=20
=20
=20
int main()
{
using namespace std;
=20
A a;
=20
C *cp=3Dstatic_cast<C *>(&a);
=20
cp->test();
=20
cout<<"a=3D "<<cp->a<<" b=3D "<<cp->b<<endl;
=20
cout<<"sizeof(A)=3D "<<sizeof(A)<<" sizeof(C)=3D "<<sizeof(C)<<endl;
}
=20
=20
Ioannis
=20
* Ioannis Vranos
* Programming pages: http://www.noicys.f2s.com
<http://www.noicys.f2s.com/>=20
* Alternative URL: http://run.to/noicys
=20
-----Original Message-----
From: dev...@li...
[mailto:dev...@li...] On Behalf Of Jason
Hardman
Sent: Sunday, October 21, 2001 1:20 AM
To: Dev-C++
Subject: Re: [Dev-C++] Strange effect
Hi, I'm back now. I've just been to see a great Depeche Mode concert
(WOW!).
=20
As I mentioned I was writing the explanation of what I think is really
happening quickly. I'll try again and see if it comes out right.
=20
You have two classes one derived from the other, the derived class has a
method that overrides one in the base. In other words two methods with
the same name but different implementations. Now pretend that the two
methods are actually *two* functions which are passed a pointer to a
struct of some sort, which is basically how a method is implemented
(don't complain, it's an analogy). When you turn pointer to the base
type into an pointer to the derived type, even if it isn't a derived
object, then you are telling the compiler that you want to use the
object as a derived type. So when you call a method via that pointer the
compiler thinks that you are really using a derived object and will try
to find the correct function. Because both the functions have the same
name, it will find a "test" function and pass the "this" pointer to that
function that belongs to derived type, even though the "this" really
points to a base object.
=20
I hope you are following me so far? I understand the idea in my head but
it's not easy for me to explain properly. Both the functions (methods)
do something, however they don't try to access anything through the
"this" pointer. That means that you won't get any problems like you
would if you tried accessing something that doesn't exist in base, but
is expected of derived.
=20
So all that happens is the derived "test" function is called and passed
a pointer it doesn't use. The function is hard coded to print out "C" in
this case.
=20
That is the why (AFAICT) what happens, happens. Whether the compiler
should complain I don't know, it depends upon what the standard says
about this case. It's only the fact that the two methods have the same
name that let's this work the way it does.
=20
Does all this scan? I am pretty certain that this is what is happening
internally.
=20
If C wasn't derived from A and you managed to cast A into C then, in
theory at least, you would get the same result. Note I have not tested
this. I think maybe that static_cast would not allow it to happen, so a
reinterpret_cast would be needed. This is just a thought, and may not be
an actual truth.
=20
Regards, Jason.
|