Re: The differences between the object and the pointer points to
object
On Dec 9, 8:17 am, kailang.d...@gmail.com wrote:
Hello,everybody
I have a program as follows.
class ClassA
{
public:
int buff[1];
virtual void test(void) {cout<<"ClassA::test()"<<endl;}
};
void entry(void)
{
cout<<"Hey,i am here!"<<endl;
}
ClassA Obj1,Obj2,*pObj;
int main()
{
pObj=&Obj2;
//Test group 1
Obj2.test();
pObj->test();
//Obj1.buff[1] covers the pvftable field of Obj2
int vtab=(int)(entry);
You should use reinterpret_cast<>, and you have to be able to
guarantee that an int is large enough to hold a function pointer, or
this conversion is undefined.
Obj1.buff[1]=(int)&vtab;
You can't rely on the virtual table having a specific layout, or being
in a specific place, or holding certain types of data (and certainly
not on it being able to use a function pointer cast to an int), or the
layout of global variables in memory being somehow related to the
order you've declared them in.
It appears that you are attempting to do this:
ClassA Obj1, Obj2;
In hopes that Obj2 will always come after Obj1 in memory, and that
Obj2's vtable entries come immediately after the data for Obj1, and
that by accessing past the end of Obj1's data array, you're
overwriting the appropriate vtable entry with valid data. All of that
is *entirely* outside the scope of C++, and the program is undefined.
Any weird behavior you see is arguably off-topic here.
You'd be better served by doing whatever it is you're trying to do
using normal, well-defined concepts like inheritance, or function
pointers. This is one way to do what you're trying to do, with
inheritance:
class ClassA {
public:
virtual void test () {cout<<"ClassA::test()"<<endl;}
};
class ClassB : public ClassA {
public:
void test () {cout<<"Hey,i am here!"<<endl}
};
ClassA Obj1;
ClassB Obj2;
int main () {
Obj1.test();
Obj2.test();
}
Using a function pointer can give you the same behavior as the
intended behavior of your original program (I did not test or compile
this):
void default_test () { ... }
void entry () { ... }
class ClassA {
public:
void (* test) ();
ClassA () : test(default_test) { }
};
void elsewhere () {
ClassA obj;
obj.test = entry;
obj.test();
}
Using a functor would give you more flexibility. There are many other
ways to accomplish the same sort of thing as well, all that *are*
defined by C++.
Why are you trying to do it this way, anyways?
Jason
//Test group 2
Obj2.test();
pObj->test();
return 0;}
The result is:
ClassA::test()
ClassA::test()
ClassA::test()
Hey,i am here!
Then,it is the point that i am confused.
In my viewpoint,after covering the pvftable field of Obj2,both Obj2
and pObj should invoke the function entry and print "Hey,i am here!".
Then i disassemble the program,it likes as follow
Obj2.test();
00401202 mov ecx,offset Obj2 (0042e168)
00401207 call @ILT+20(ClassA::test) (00401019)
pObj->test();
0040120C mov eax,[pObj (0042e158)]
00401211 mov edx,dword ptr [eax]
:
:
0040121B call dword ptr [edx]
These disassembly codes may have explain the print result.
But can anybody explains the differences between the object and the
pointer points to object?
Thanks a lot!
-Bruce