|
From: Ioannis V. <no...@ya...> - 2001-10-21 13:17:12
|
I forgot to mention that *static* member functions have only one instance for all the objects of a class. Non-static member functions are created each one for an object, that is any object has its own *instance* of each non-static member function. =20 =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 -----Original Message----- From: Jason Hardman [mailto:jas...@bt...]=20 Sent: Sunday, October 21, 2001 2:00 PM To: Ioannis Vranos Subject: Re: [Dev-C++] Strange effect It seems you don't understand what I am explaining. Do you believe that each time you create an object of a particular class you are recreating a set of methods specifically for that object? Or do you believe that there are only a single set of methods for every object of a type, and the objects only contain the data? Note that there is a distinction between an object and a class. When you report the size of the A and C objects note that A is 1 byte and C is 2 bytes, which is constistent with the two char's that are declared. If a method code was also part of the object then the values would be much bigger. =20 Note that you are actualy over running the A object in your code and accessing undefined memory when you access b, but it doesn't cause any errors because of the way memory is managed by the compiler. I expect that if larger data was used then problems would crop up. =20 I might try again to get across the idea again later, because I still think it aproaches the truth of the situation. If you want you can report the error to the team that develop gcc and see what they say, they will know better than either of us. =20 I'm sure we'll discuss this some more but I'll leave it there for now. =20 Jason. ----- Original Message -----=20 From: Ioannis Vranos <mailto:no...@ya...> =20 To: Dev-C++ <mailto:dev...@li...> =20 Sent: Sunday, October 21, 2001 12:21 PM Subject: RE: [Dev-C++] Strange effect 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. |