首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

类的public成员函数的初始化及使用有关问题

2012-03-12 
类的public成员函数的初始化及使用问题classA{public:A(){printf( create\n )}~A(){printf( destory\

类的public成员函数的初始化及使用问题
class   A  
{
public:
        A(){printf( "create\n ");};
        ~A(){printf( "destory\n ");};
        virtual   int   func1(){printf( "In   func1\n ");return   2;};
        int   func2(){printf( "In   func2\n ");return   3;};
public:

        char   name;
};

void   main()
{
       
       
        char   *   p   =   NULL;

        ((A*)p)-> func2();
        ((A*)p)-> func1();
     
}

在上面的代码中,p-> func2()可以执行,   但p-> func1()会出错。   从生成的ASM   code看,   在调用func2时,VC2005可以其函数地址,所以能够执行,而func1时,因为vtbl为非法值,所以报错。
我的问题是,谁能解释一下类中的pulbic   函数为什么可以这么使用。



[解决办法]
去看《深度探索C++对象模型》
和public不public没关系,你这个纯属幸运。
[解决办法]
int func2(){printf( "In func2\n ");return 3;};
这两个函数都没有使用成员变量,
A* p=0;
p-> func2()总是会成功的
[解决办法]

lz,你的理解还是有点不清晰,是这样的

为了讲解,我重新写了个例子

struct TEST
{
int date;
void fun2() {

date = 100;
}
virtual void fun1()
{

}
};


1)

fun2 是个普通的成员函数,当你调用fun2的时候

编译器是不会检查fun2内部是否访问了成员变量的,比如

TEST* p = 0;

p-> fun2();

编译可以通过,只是运行的时候出错了,因为this指针为空

在函数内部通过偏移量来找date成员变量的时候,访问了非法地址

fun2内的 date = 100; 汇编代码如下

00401083 mov eax,dword ptr [this]
00401086 mov dword ptr [eax+4],64h

看到了吗 [eax+4] 这个就是date成员变量的地址,通过this偏移4

得到(因为vftable指针占了4字节,所以第一个变量偏移4)

运行到这里的时候 this 为空,所以是 0, 0 + 4 = 4

程序去访问地址 4,当然这个是非法的地址,所以程序挂掉

2)

当你调用 fun1() 的时候,

TEST* p = 0;

p-> fun1();

fun1() 是个虚函数,因此许通过虚表(vftabe)去找到这个函数地址

你可以把vftabe的指针看做是TEST的第一个成员变量,

需要同过这个变量去找到响应的vftable,这个成员变量的偏移值为 0

这样就相当访问了类的一个

成员变量,如同上面的1)this 指针为空,当然所以就出现了访问非法地址

的运行错误

这是调用fun1相应的汇编码

TEST* p = 0;
0040101E mov dword ptr [p],0

p-> fun1();
00401025 mov eax,dword ptr [p] // 这里[p] 0 ,所以 edx 为 0
00401028 mov edx,dword ptr [eax] // [eax] 等于 [0],访问0地址,当然非法咯
..........
..........


热点排行