C++调用类成员函数的过程

我知道C++有一个虚函数列表,对象有指向虚函数列表的指针,对于有虚函数的类对象调用虚函数时通过虚函数列表里面的指针实现的。。但是对于普通的非虚函数是怎么实现调用的呢、?是... 我知道C++有一个虚函数列表,对象有指向虚函数列表的指针,对于有虚函数的类对象调用虚函数时通过虚函数列表里面的指针实现的。。但是对于普通的非虚函数是怎么实现调用的呢、? 是怎么找到非虚函数的入口地址? 好像类对象里面只有类的一些数据成员。。求解惑 求详细的内存层次的变化 展开
 我来答
lkjhggv
2013-09-10 · TA获得超过3063个赞
知道大有可为答主
回答量:1550
采纳率:66%
帮助的人:1305万
展开全部
程序运行时内存中有一个区域【代码区】,所有代码段都存放在这里,包括虚函数和非虚函数
普通函数调用时,直接转换成代码去区的地址,生成文件时就定了
类的虚表可以看成是类的静态数据成员,类的每个对象有个指针指向这个虚表,即为虚表指针
当虚函数调用时,就是从虚表指针找到虚表,进而找到了虚函数的地址
更多追问追答
追问
比如:class A{ public:void f(){} };
A a;

a.f(); //调用f();

我知道编译时类中函数会在代码区生成,还有一个偏移量来定位什么的(这不是很懂), 但是a.f是怎么知道代码区f()函数的绝对地址的? 就是想知道运行a.f()时,内存里面发生了什么变化。
追答
class A
{
public:
    void f() {}
    virtual void g() {}
};
class B : public A
{
public:
    void h() {}
    virtual void g() {}
};
void Test(A& a)
{
    a.f();
    a.g();
}

以上是代码

下面是Test两个函数调用的汇编代码

 a.f();
001F6FCE  mov         ecx,dword ptr [a]  
001F6FD1  call        A::f (01F1433h)  
 a.g();
001F6FD6  mov         eax,dword ptr [a]  
001F6FD9  mov         edx,dword ptr [eax]  
001F6FDB  mov         esi,esp  
001F6FDD  mov         ecx,dword ptr [a]  
001F6FE0  mov         eax,dword ptr [edx]  
001F6FE2  call        eax  
001F6FE4  cmp         esi,esp  
001F6FE6  call        __RTC_CheckEsp (01F12E9h)

由此可见,f函数直接寻址(在编译时就已经确定地址了01F1433h),而g函数通过虚指针寻址

韧劲9
2015-06-06 · TA获得超过9224个赞
知道小有建树答主
回答量:1638
采纳率:92%
帮助的人:349万
展开全部
在static成员函数中传递类本身的指针,就可以在内部调用这个指针的具体动作(做一下强制转换)。
由于static成员函数本身的作用域是属于类的public/protected的,所以它既能被外部调用,也能直接使用类内部的/public/protected/private成员。

这解决了不能通过C的函数指针直接调用C++的类普通public成员函数的问题。

struct test
{
char (*cptr_func)(void *);
};

class C
{
public:
static char cpp_func(void *vptr){
//针对这个对象调用他的成员函数
return static_cast<C*>(vptr)->_xxx();
}
char _xxx(){
std::cout<<"hei! _xxx called"<<std::endl;
return 'a';
}
};

int main()
{
struct test c_obj;
class C cpp_obj;

c_obj.cptr_func = C::cpp_func;
std::cout<< c_obj.cptr_func(&cpp_obj) <<std::endl;

return 0;
}
#include <iostream>

struct test
{
char (*cptr_func)(void *);
};

char cpp_friend_func(void*);

class C
{
friend char cpp_friend_func(void *vptr);
public:
char _xxx(){
std::cout<<"hei! _xxx called"<<std::endl;
return 'a';
}
};

char cpp_friend_func(void *com_on) //friend function have the ability of calling class public/private/protected member functions
{
return static_cast<C*>(vptr)->_xxx();
}
int main()
{
struct test c_obj;
class C cpp_obj;

c_obj.cptr_func = cpp_friend_func;
std::cout<< c_obj.cptr_func(&cpp_obj) <<std::endl;

return 0;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式