欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

让类成员函数指针成为可调用对象

来源:本站整理 作者:zmh009_NAME 时间:2017-01-03 TAG: 我要投稿

类成员函数指针实践上是一个指针类型,不可直接通过调用运算符()作为可调用对象调用,一般调用该类成员函数指针需要指定该指针对应的对象。
    一般情况下调用类成员函数指针:
// a.h
#ifndef A_H
#define A_H
#include
using std::cout;
using std::endl;
 
class A{
public:
    void print();
};
#endif
 
// a.cpp
#include "a.h"
void A::print()
{
    cout "A::print"
}
 
// main.cpp
#include "a.h"
using pClassF = void (A::*)(); // 声明类A的成员函数指针类型
 
int main()
{
    pClassF pf= &A::print; // 定义类成员函数指针,不支持函数到指针的自动转换
    A a;
    (a.*pf)(); // .*、->*成员访问符,因为访问优先级则(a.*pf)的括号必须添加
    return 0;
}
其中A::*表示是类A的成员指针,接着的()表示是无参的函数类型;
如果直接是pf()则出错,因为pf不是可调用对象其未指定对象执行;
使用的std::function模板类:
因为类的成员函数执行时,会在参数列表添加参数--隐式的this实参,在function模板类调用时可以传入对象实现this的功能(传入的对象不一定是指针类型),function判断如果是类成员函数指针,则会将通过该对象使用成员访问运算符,实现类成员函数指针的调用功能(具体function如何判断是类成员函数指针还是普通函数指针,本人现在不清楚,如果有理解错误地方望指正):
// main.cpp ,头文件a.h与源文件a.cpp之前相同
#include
#include "a.h"
using std::function;
using pClassF = void (A::*)(); // 声明类A的成员函数指针类型
 
int main()
{
    auto pf= &A::print; // 定义类成员函数指针,不支持函数到指针的自动转换
    A a;
    
    // void 表示成员函数的返回值,A表示传入的参数类型为A,因为是模板类型则要求可以准确匹配,且A类型可以调用对应的成员函数,如果是const A类要调用const成员函数
    functionvoid (A)> fnt = pf;
    fnt(a);
    return 0;
}
通过fnt(a)传入对象a,在function里通过a与成员访问符调用成员函数。
使用std::mem_fn标准库函数:
mem_fn函数可以通过成员函数指针的类型自动推断可调用对象类型,用户无须指定。在可调用对象里有接收对象与对象指针的一组调用运算符重载函数,可使用对象或对象指针调用该成员函数,使用方式与function相同:
// main.cpp,头文件a.h与源文件a.cpp之前相同
#include
#include "a.h"
using std::mem_fn;
using pClassF = void (A::*)() const; // 声明类A的成员函数指针类型
 
int main()
{
    auto pf= &A::print; // 定义类成员函数指针,不支持函数到指针的自动转换
    A a;
    auto fnt = mem_fn(pf); // mem_fn通过成员函数指针自动推导可调用对象类型
    fnt(a); // 使用对象调用成员函数
    fnt(&a); // 使用对象指针调用成员函数
    return 0;
}
fnt(a)与fnt(&a)的结果一致。
使用通用的函数适配器bind生成可调用对象,需要命名空间std::placeholders表示在bind传给函数的参数:
与function类似,将隐式传入this形参转为显示传入对象;与mem_fn类似,生成的可调用对象有接收对象与对象指针的一组重载调用运算符函数:
// main.cpp,头文件a.h与源文件a.cpp之前相同
#include
#include "a.h"
using namespace std::placeholders; // 用于表示bind传入指定函数的形参位置,即bind的_1、_2、...、_n等
using pClassF = void (A::*)() const; // 声明类A的成员函数指针类型
 
int main()
{
    auto pf= &A::print; // 定义类成员函数指针,不支持函数到指针的自动转换
    A a;
    auto fnt = bind(pf,_1); // _1表示在bind该位置的参数传给pf,并成为pf的第一个形参
    fnt(a); // 使用对象调用成员函数
    fnt(&a); // 使用对象指针调用成员函数
    return 0;
}
详细说明可查阅bind函数,fnt(a)与fnt(&a)的结果一致。
 

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载