在一般的方法中,基本上传递函数都是通过传递函数指针的方式来实现。但是最近发现,频繁的传递函数、类成员函数不太是一个好的办法,所以在这里梳理一下常见的几种方法以及如何更方便的传递函数。
如果是普通函数的话,一般这样
#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
std::function
C++
Utilities library
Function objects
std::function
Defined in header | |
template< class > class function; | (since C++11) |
template< class R, class... Args > class function<R(Args...)>; | (since C++11) |
Class templateis a general-purpose polymorphic function wrapper. Instances of
std::function
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
. 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
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函数对应的参数列表。
因此,它可以被用于回调机制,暂时保管函数或函数对象,在之后需要的时候再使用,使回调机制拥有更多的弹性。(我主要就是用它来实现回调函数)