C++通过什么机制调用类的成员函数?

C++通过什么机制调用类的成员函数?,第1张

如果是类的静态函数,那么你可以把它当作普通函数看待,没有任何区别。

如果是类的非虚非静态函数,和调用普通函数基本一样,只不过隐藏的传入了一个参数:this指针。另外就是许多编译器在编译的时候会优化成为__thiscall调用方式。

如果是虚函数,那就是先读取对象的虚函数表,然后得到函数指针,之后就和上面一样了。

简单说:在put函数的定义处,首先得有一个student的对象,然后通过对象调用input,调用时实参的个数,类型和input函数中的形参个数,类型都要一致。

具体解释:

c++的成员函数根据其调用的不同,大致可以分为4类:内联成员函数,静态成员函数,虚成员函数和上述3种以外的普通成员函数。从本质来说类成员函数和全局函数在调用上并没有差别,非内联函数的在调用时,基本上都包括如下的过程:函数的参数入栈,eip指针值入栈,然后跳到函数体的地址,执行函数体对应的代码,执行完毕调整栈帧。下面就按照上述4个分类进行分析,先来说一下普通的成员函数:

普通的成员函数在被调用时有两大特征:

1 普通的成员函数是静态绑定的,

2 普通的成员函数调用时编译器隐式传入this指针的值。

通过代码分析一下:

#include <iostream>

using namespace std;

class Test

{

public:

void Print(int i);

};

void Test::Print(int i)

{

cout<<i<<endl;

}

int main()

{

Test p=new Test();

p->Print(2);

system("pause");

}

上面Print函数符合上面所说4类的中的普通成员,所谓的静态绑定实质是c++源代码编译时,编编译器在p->Print();处翻译成直接调用Test类中Print()的汇编代码,也就是编译期编译器就确定了被调函数的相对地址。而所谓的动态绑定实质是,源码在编译的时候,编译器不是翻译成直接调用Test类中Print()的汇编代码,而是翻译成一个查找虚表,得到到函数的相对地址的过程。

C++成员函数中的调用约定应该是__thiscall,而且不可由程序员指定,你那个代码我在GCC上编译不通过,不知道VC是咋么搞的,又用VC debug了以下发现是delete试图去 *** 作 0x00000001 这个地址,当然会出错,相信是p()以后留下了什么后遗症没有清除,我也懒得去研究了。

另外你的基类中没有虚析构函数,内存泄露啦!,你试试看把~A()前的virtual去掉运行看看~B()会不会调用

#include<iostream>

using namespace std;

#define CALL // __stdcall

class A

{

public:

CALL A()

{

}

virtual void CALL output()

{

printf("Class An");

}

virtual void CALL output2()

{

}

virtual CALL ~A(){printf("~A()");};

};

class B :public A

{

private:

void CALL output()

{

printf("Class Bn");

}

public:

CALL ~B(){printf("~B()");}

};

class C:public A

{

public :

void CALL output()

{

printf("Class Cn");

}

CALL ~C(){printf("~C()");}

};

int main(int argc, char argv[])

{

typedef void (CALL pfun)();

A pa = new B;

pfun p = (pfun)(long)((long)pa);

p();

delete pa;

return 0;

}

PS: 百度又抽了

在C++中,“类函数指针”和传统的“函数指针”,是两个完全不同的东西。

你取一个类的成员函数的地址,得到的是一个类函数指针,也叫成员函数指针。即使你的成员函数定义看起来和普通函数原型完全一样,它也和这个原型的普通函数指针完全不同,彼此之间不能转换。

PyEval_SetTrace要求传入的是一个传统的函数指针,你传入一个类函数指针,当然是不行的。编译器报错是说无法将一个类函数指针转换为函数指针。

C++的类函数指针,是一个非常难用的东西,有非常多奇怪的特性,而且不同编译器对它的支持大不相同,是C++著名的复杂性来源之一,建议不要使用。

你想要的东西,实际上是一个“委托”的概念,不过可惜的是C++并不支持委托。使用boost::function可以实现类似功能,但python的C API接口却不支持boost::function,所以也不行。

你这种情况,最简单的方法还是用传统的函数指针,使用普通函数包装下类的成员函数,然后把普通函数的指针传给python。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12156692.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存