c++ 如何优雅的传递函数以及类成员函数

1 篇文章 0 订阅
1 篇文章 0 订阅

在一般的方法中,基本上传递函数都是通过传递函数指针的方式来实现。但是最近发现,频繁的传递函数、类成员函数不太是一个好的办法,所以在这里梳理一下常见的几种方法以及如何更方便的传递函数。

如果是普通函数的话,一般这样

 

#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 <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 expressionsbind 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函数对应的参数列表。

因此,它可以被用于回调机制,暂时保管函数或函数对象,在之后需要的时候再使用,使回调机制拥有更多的弹性。(我主要就是用它来实现回调函数)

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值