成员函数指针 还有std::function之类

遇到了一个需要在公用类里取得其他类的对像和成员函数,然后在公用类里解决之后回调的问题。 不过传入的函数由于不知道类的类型,所以在公用类里不知道怎么处理。

查了一些相关的东西,看到了一些知识,记一下:

类的静态成员函数采用与一般函数指针相同的调用方式,而受this指针的影响,类的非静态成员函数与一般函数指针是不兼容的,指向不同类的非静态成员函数的指针也是不兼容的。类的成员函数指针的长度随类的定义与否、类的继承种类和关系而变, 与一般函数指针不同,指向“类”的成员函数的指针不仅包含成员函数地址的信息,而且包含与类的属性有关的信息,因此,一般函数指针和类的成员函数指针是根本不同的两种类型,当然,也就不能用一般函数指针直接调用类的成员函数。

于是最后尝试的是通过所有调用的类都需要共同继承与一个父类,然后类型转化为父类的指针之后传给公用类,再在公用类里使用父类类型来回调,这样暂时可以行得通,但是调用的时候就需要转化,而且如果传入的对象指针与函数指针不是一个类的,那么只有运行时才会出现错误,所以感觉不太好,但是目前还没有想到比较好的方法。

还有一个就是指针赋值这些操作会根据左操作数的类型来判断左操作数的指针指向右操作数对象的哪个偏移地址。如果是其他类型的指针(如void*),则指向对象的首地址。所以不要以为单纯的指针赋值就是直接地址的传递,其实会有一个内在的转化,所以要注意一点。由于不同C++编译器对C++对象模型的结构可能是不一样的。比如说,VC++系列是将虚函数表指针放在对象首地址,而GCC系列的编译器则是将虚函数表指针放在对象地址尾部。

std::function和bind其实是 #include <functional> 里面一个c++的可以更方便灵活的管理函数指针的函数,吧函数抽象成一个模板,然后进行操作,其实原理和操作指针是没有什么区别的。

一些使用过程中的注意事项:

  • (1)关于可调用实体转换为std::function对象需要遵守以下两条原则:
    a. 转换后的std::function对象的参数能转换为可调用实体的参数
    b. 可高用实体的返回值能转换为std::function对象的(这里注意,所有的可调用实体的返回值都与返回void的std::function对象的返回值兼容)。
  • (2)std::function对象可以refer to满足(1)中条件的任意可调用实体
  • (3)std::function object最大的用处就是在实现函数回调,使用者需要注意,它不能被用来检查相等或者不相等
    std::function<返回值(参数值)> = 函数;
    bind是将参数bind进函数中,bind后的函数记得参数要相应的减少。

 

成员函数相当于一个多一个参数的函数,第一个参数是调用它的对象!

一个例子:

Utils utils("Vicky");
auto sayHello = std::bind(&Utils::sayHello, utils/*调用者*/, std::placeholders::_1/*参数1*/);
sayHello("Jack");

还有有一点是使用auto这里要注意一下,有很多情况下你需要显示的说明类型,用auto的话可能很多函数会无法转化识别。

想起上面还尝试用void指针来转化,其实也没办法,任何类型的指针都可以直接赋值给它,无需进行强制类型转换,但是相反就不行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值