类的成员函数作为函数指针
网上找了半天没找到,还是看官方文档比较清晰:std::function - cppreference.com (polytechnique.fr)
同时给出自己设计C类型的成员函数指针的形式。
其实函数指针要给函数的地址,那么地址一定要是全局的才可以。所以实现有两种思路,一种是直接再类中定义一个静态成员函数;另一种是可以用全局函数回调std::function定义的可调用对象函数。std::function的好处是可以局部使用不用全局。
#include<iostream>
#include<functional>typedef int(*AddPtr)(int, int);std::function<int(int, int)> add_callback;class Cal
{
public:static int s_add(int x, int y){std::cout << "static fun : \n";return x + y;}int add(int x, int y){return x + y;}
};void fun(int a, int b, std::function<int(int, int)> ptr)
{std::cout << "use function :\n";int res = ptr(a, b);std::cout << "a + b = " << res << "\n";
}void fun(int a, int b, AddPtr ptr)
{std::cout << "no use function :\n";int res = ptr(a, b);std::cout << "a + b = " << res << "\n";
}// 全局函数形式
int g_add(int x, int y)
{return add_callback(x, y);
}int main()
{Cal cal;add_callback = std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2);fun(5, 7, add_callback);AddPtr ptr = g_add;fun(5, 7, ptr);AddPtr ptr2 = &Cal::s_add;fun(5, 7, ptr2);
}
如果有多个类的成员函数都想使用函数指针的形式调用,每个成员函数都要写一个全局的函数非常的麻烦,所以可以使用模板让编译器来生成的代码,这样写一份等于无数份。具体示例如下:
#include <type_traits>
#include <iostream>
#include <utility>
#include<iostream>
#include<functional>typedef int(*AddPtr)(int, int);class Cal
{
public:int add(int x, int y){return x + y;}
};void fun(int a, int b, AddPtr ptr)
{std::cout << "no use function :\n";int res = ptr(a, b);std::cout << "a + b = " << res << "\n";
}template <typename Callable>
union storage
{storage() {}std::decay_t<Callable> callable;
};template <int, typename Callable, typename Ret, typename... Args>
auto fnptr_(Callable &&c, Ret (*)(Args...))
{static bool used = false;static storage<Callable> s;using type = decltype(s.callable);if (used)s.callable.~type();new (&s.callable) type(std::forward<Callable>(c));used = true;return [](Args... args) -> Ret{return Ret(s.callable(std::forward<Args>(args)...));};
}template <typename Fn, int N = 0, typename Callable>
Fn *fnptr(Callable &&c)
{return fnptr_<N>(std::forward<Callable>(c), (Fn *)nullptr);
}int main()
{Cal cal;// Right :// auto fun_ptr = std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2);// AddPtr lambda_add = fnptr<int(int,int)>([&fun_ptr](int x, int y){return fun_ptr(x, y);});// AddPtr lambda_add = fnptr<int(int,int)>(std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2));// AddPtr lambda_add = fnptr<int(int,int)>(fun_ptr);// fun(5, 6, lambda_add);// Error :std::function<int(int, int)> fun_ptr = std::bind(&Cal::add, cal, std::placeholders::_1, std::placeholders::_2);AddPtr lambda_add = fnptr<int(int,int)>(fun_ptr);fun(5, 6, lambda_add);}
类的成员函数作为函数指针相关推荐
- C++57个入门知识点_40 常成员函数(用于定义不可修改类内部成员变量的函数,一般用来修饰Get函数;常成员函数this指针:const T* const;常成员函数内部变量修改方法:强转/关键字)
前面我们已经学习了C++中重要的知识点,特别是虚函数可能会有些懵逼,但是需要我们在实践中不断的理解和尝试,写代码是进步最快的方式,接下来将会介绍一些简单但很重要的知识点,本篇介绍常成员函数. 总结: ...
- 少说话多写代码之Python学习048——类的成员(supper函数)
继承父类的构造函数,前面我们在子类的构造函数中调用:父类__init__(self),调用父类的构造函数.这种做法称之为绑定未绑定的父类构造函数.在Python3.0中可以使用supper函数 实现继 ...
- 类的成员函数指针和mem_fun适配器的用法
先来看一个最简单的函数: void foo(int a) {cout << a << endl; } 它的函数指针类型为 void (*)(int); 我们可以这样使用: vo ...
- 浅析C++中的this指针 通过空指针(NULL)可以正确调用一些类的成员函数?
有下面的一个简单的类: class CNullPointCall { public: static void Test1(); void Test2(); void Test3 ...
- 一文带你入门C++,类与对象、6个默认成员函数、this指针以及static关键字。
C++98关键字:63个 一.命名空间规则(namespace) 1.命名空间可以解决函数.全局变量名重复的问题,包在不同的命名空间里的重复函数,实际就是两个完全无关的函数. 2.命名空间允许续嵌套: ...
- C++ 类的成员函数指针 ( function/bind )
这个概念主要用在C++中去实现"委托"的特性. 但现在C++11 中有了 更好用的function/bind 功能.但对于类的成员函数指针的概念我们还是应该掌握的. 类函数指针 就 ...
- 怎么将一个类的成员函数作为指针传递给另一个类的成员函数
今天帮同学解决了一个问题,怎么把一个类的成员函数作为指针传递给另一个类的成员函数. 以前只接触过C语言中的函数指针: #include <iostream.h> void add(int ...
- 一般函数指针和类的成员函数指针
转载请注明原文网址: http://www.cnblogs.com/xianyunhe/archive/2011/11/26/2264709.html 函数指针是通过指向函数的指针间接调用函数.函数指 ...
- 类的成员函数指针(比较深入)
From:http://blog.csdn.net/hairetz/archive/2009/05/06/4153252.aspx 个人感觉对于类的成员函数指针这块讲解的比较深入详细 推荐阅读 / 先 ...
- 类的成员函数指针和静态成员函数指针 调用成员函数***
C++提供static这个关键词对静态成员进行声明,静态成员函数和类的实例化无关,对于同一类来说,静态成员函数是所有类的对象共享的.而普通成员函数需要实例化才能调用,对于每一个实例来说,普通成员函数是 ...
最新文章
- java序列化和RMI
- AI时代数据之争,我们需要什么样的“数据权”?
- GXGetImage方式连续采集和发送软触发采集
- js之操作JSON数据
- C语言fputs()函数(把字符串写入到指定的流 stream (文件指针)中)
- Excel中vlookup函数的使用方法
- Linux find和grep的区别
- sed tr 去除PATH中的重复项
- Navicat for MySQL工具创建mysql数据库定时器
- android手机误删通讯录恢复
- linux 目录权限,Linux目录权限整理总结
- linux服务器删除weblogic,linux weblogic安装和卸载
- 韩立刚老师《计算机网络》笔记3
- 【Python 24】52周存钱挑战4.0(函数)
- 宏病毒的研究与实例分析04——实战分析
- matlab画图不显示中文_如何解决 Matlab 画图时中文显示乱码的问题?
- 使用 Android Studio 内置的模拟器体验原生安卓
- VR系列——Oculus最佳实践:七、虚拟幻境头晕(下)
- python生存曲线_生存曲线的估计方法(3):寿命表法
- python工具——pypinyin 汉字转换拼音