在一般的方法中,基本上传递函数都是通过传递函数指针的方式来实现。但是最近发现,频繁的传递函数、类成员函数不太是一个好的办法,所以在这里梳理一下常见的几种方法以及如何更方便的传递函数。
如果是普通函数的话,一般这样
#include <iostream> int add(int a, int b) { return a + b; } int main() { int (*func) (int, int); func = add; std::cout << "func :\t" << func(10, 20) << std::endl; std::cout << "Hello World!\n"; getchar(); }
如果是类成员函数的话,我这里使用两个类A和B,在B类中存放A类的函数,然后通过B类的方法来调用A类指定的那个成员函数,
A.h
#pragma once #include <iostream> class A { public: int add(int a,int b) { std::cout << "Hello A:func" << std::endl; return a + b; } };
B.h
#pragma once #include <iostream> class A; //前向声明
class B {
public: A *locala; int (A::*func)(int ,int); int run() { return (locala->*func)(10, 20); } };
main.cpp
#include <iostream> #include "A.h" #include "B.h" int main() { A a; B b; b.locala = &a; b.func = &A::add; std::cout << "Class B func return :\t"<<b.run() << std::endl;; std::cout << "Hello World!\n"; getchar(); }输出结果:
在实际使用中,如果传入的类不同,以及函数的参数发生改变等情况,都会产生十分麻烦的修改程序代码的问题,而且频繁使用这种方式来实现代码也违背了程序的许多设计原则,在这里我们可以看一下C++11 的新标准
std::function
C++
Utilities library
Function objects
std::function
Defined in header <functional>
template< class > class function; /* undefined */
(since C++11)template< class R, class... Args > class function<R(Args...)>;
(since C++11)Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown.
std::function satisfies the requirements of CopyConstructible and CopyAssignable.
机翻:
类模板std :: function是通用的多态函数包装器。 std :: function的实例可以存储,复制和调用任何CopyConstructibleCallable目标-函数,lambda表达式,bind表达式或其他函数对象,以及指向成员函数的指针和指向数据成员的指针。
存储的可调用对象称为std :: function的目标。 如果std :: function不包含目标,则称为空。 调用空std :: function的目标会导致std :: bad_function_call抛出异常。
std :: function满足CopyConstructible和CopyAssignable的要求。
简单来说,function是一个封装,它可以针对可复制的、可调用的对象或者函数,当调用一个function对象时,如果这个对象是空的,就会抛出std :: bad_function_call这个异常,我们可以捕捉这个异常。最后,function是可复制可拷贝赋值的。
通过function和bind函数,在这里将类成员函数的调用重新实现一下:
A.h
#pragma once #include <iostream> class A { public: int add(int a,int b) { std::cout << "Hello A:func" << std::endl; return a + b; } };
B.h
#pragma once #include <iostream> #include <functional> class A; //前向声明 class B {
public: std::function<int(int one, int two)> localfunc; int run() { return localfunc(10, 20); } };
main.cpp
#include <iostream> #include "A.h" #include "B.h" int main() { A a; B b; b.localfunc = std::bind(&A::add, &a, std::placeholders::_1, std::placeholders::_2); std::cout << "Class B func return :\t"<<b.run() << std::endl;; std::cout << "Hello World!\n"; getchar(); }输出结果:
这样实现的好处就是,在B类中先定义了localfunc这个函数,它指定了两个参数,后期调整的话,如果扩展参数或者减少参数,我们可以直接更改bind函数对应的参数列表。
因此,它可以被用于回调机制,暂时保管函数或函数对象,在之后需要的时候再使用,使回调机制拥有更多的弹性。(我主要就是用它来实现回调函数)