首先看:
class TestMem{
public:
char m_char;
int m_iMember;
int m_iMember2;
TestMem()
{
m_iMember = 1;
m_iMember2 = 2;
}
int Print()
{
printf("print in Print!\n");
return 0;
}
};
int main(int argc, char* argv[])
{
int iSize = sizeof(TestMem);
printf("class size:%d\n", iSize);
return 0;
}
此处输出的是12,类的成员函数并没有在计算的大小之内,因为成员函数在编译后存放在内存的代码区。
typedef int(TestMem::*MEMFUN)();
TestMem *p = new TestMem;
MEMFUN pPrint = p->Print;
MEMFUN pPrint2 = p->Print2;
GOLBAL pStatic = TestMem::Print_Static;
printf("p->Print: %p\t p->Print: %p\t TestMem::Print_Static: %p\n", pPrint, pPrint2, pStatic);
delete p;
p = 0;
p->Print();
printf("after delete :%p\n", p);
通过以上代码可以打印出成员函数的地址,在调用成员函数的时候,编译器会在编译时决议出正确的普通成员函数地址,并将对象的地址以this指针的方式,做为第一个参数传递给普通成员函数,以此来进行关联。
但是在delete p之后,调用p->Print() ,如果再Print中没有使用类成员对象,是可以正常运行的。
不知道该怎么理解?试了一下
TestMem *ptr = (TestMem*)(0);
ptr->Print();
也是可以正常输出的,不知道编译器对于代码区具体的 管理 方式,应该是根据类成员函数的偏移量来决定,如果Print()中没有调用类成员对象,Print作用相当于全局函数。
编译器为VC 6.0,还没在GCC中试。
class TestMem{
public:
char m_char;
int m_iMember;
int m_iMember2;
TestMem()
{
m_iMember = 1;
m_iMember2 = 2;
}
int Print()
{
printf("print in Print!\n");
return 0;
}
};
int main(int argc, char* argv[])
{
int iSize = sizeof(TestMem);
printf("class size:%d\n", iSize);
return 0;
}
此处输出的是12,类的成员函数并没有在计算的大小之内,因为成员函数在编译后存放在内存的代码区。
typedef int(TestMem::*MEMFUN)();
TestMem *p = new TestMem;
MEMFUN pPrint = p->Print;
MEMFUN pPrint2 = p->Print2;
GOLBAL pStatic = TestMem::Print_Static;
printf("p->Print: %p\t p->Print: %p\t TestMem::Print_Static: %p\n", pPrint, pPrint2, pStatic);
delete p;
p = 0;
p->Print();
printf("after delete :%p\n", p);
通过以上代码可以打印出成员函数的地址,在调用成员函数的时候,编译器会在编译时决议出正确的普通成员函数地址,并将对象的地址以this指针的方式,做为第一个参数传递给普通成员函数,以此来进行关联。
但是在delete p之后,调用p->Print() ,如果再Print中没有使用类成员对象,是可以正常运行的。
不知道该怎么理解?试了一下
TestMem *ptr = (TestMem*)(0);
ptr->Print();
也是可以正常输出的,不知道编译器对于代码区具体的 管理 方式,应该是根据类成员函数的偏移量来决定,如果Print()中没有调用类成员对象,Print作用相当于全局函数。
编译器为VC 6.0,还没在GCC中试。