C++普通函数指针和类成员函数指针

举例1:普通函数指针:

	int(*fun)(double, int);
	fun = [](double a, int b) {
		cout << a << endl;
		cout << b << endl;
		return 3;
	};

	int x = fun(34, 123);

typedef定义函数指针类型:

typedef int(*padd)(int, int, int);

int add(int a, int b, int d)
{
	return a + b + d;
}

int mul(int a, int b, int d)
{
	return a * b * d;
}

int main()
{
	padd p1 = add; //p1为padd类型的变量
	p1(1, 2, 3);

	padd p2 = mul; //p2为padd类型的变量
	p2(1, 2, 3);

	return 0;
}

如果不使用typedef定义函数指针类型,则不能声明变量。
在这里插入图片描述

举例2:类成员函数指针

#include <iostream>
using namespace std;

class A {
public:
	A() = default;
	int SayHello(int a)
	{
		cout << a << endl;
		return 100;
	}
};

typedef int(A::*FP)(int); //类成员函数指针,要加一个类的作用域,四饼运算符,哈哈哈

int main()
{
	FP fp = &A::SayHello;
	A a;
	int x = (a.*fp)(3); //*fp可以称为解引用,取得函数名字(a.*fp)
	cout << x << endl;
	return 0;
}


再举个例子:
假设我们有一个类Person,其中有一个成员函数void sayHello(),我们可以使用类成员函数指针来实现回调机制:


#include <iostream>

class Person {
public:
    void sayHello() {
        std::cout << "Hello, I'm a person!" << std::endl;
    }
};

void callback(void (Person::*func)(), Person* p) {
    (p->*func)();
}

int main() {
    Person p;
    callback(&Person::sayHello, &p);
    return 0;
}

在这个例子中,callback函数接受一个类成员函数指针和一个Person对象的指针作为参数,当函数被调用时,它会使用指针调用Person对象的成员函数。

通过这种方式,我们可以将一个成员函数作为参数传递给另一个函数,从而实现回调机制,这在事件处理和异步编程中非常常见。

typedef的作用,定义一个新的类型:

class Foo {
public:
    float bar(int x) { return x * 3.14f; }
};

typedef float (Foo::*BarPtr)(int);

In this case, BarPtr is now a type that can hold a pointer to the bar member function of Foo.
这里的BarPtr就是新的类型,可以用来接收类的成员函数指针。

https://blog.molecular-matters.com/2011/09/19/generic-type-safe-delegates-and-events-in-c/
https://skypjack.github.io/2019-01-25-delegate-revised/
https://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible

https://www.ibm.com/docs/en/zos/2.3.0?topic=only-explicit-specialization-c
http://www.lucadavidian.com/2020/11/20/c-delegates/

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;


template<typename T>
void f(T&& t)
{
	if (std::is_same<int, T>::value) //T&&
	{
		cout << "int" << endl;
	}
	if (std::is_same<int&, T>::value) //T&&
	{
		cout << "int&" << endl;

	}
	if (std::is_same<int&&, T>::value) //T&&
	{
		cout << "int&&" << endl;
	}
}

template<typename T>
T sum(T t)
{
	return t;
}
template<typename T, typename ... Types>
T sum(T first, Types ... rest)
{
	int count = sizeof...(rest);
	return first + sum<T>(rest...);
}


//template <class... T>
//void f2(T... args)
//{
//	cout << sizeof...(args) << endl; //打印变参的个数
//}


template <typename...> class Foo;

template <typename A, typename B>
class Foo<A, B>
{
public:
	void output() {
		std::cout << a_ << b_ << '\n';
	}
	A a_;
	B b_;
};

template <typename A, typename B, typename C>
class Foo<A, B, C>
{
public:
	void output() {
		std::cout << a_ << b_ << c_ << '\n';
	}
	A a_;
	B b_;
	C c_;
};

template<typename>
class FF;

template<typename T, typename ...B>
class FF<T(B...)> {
public:
	void Show()
	{
		int count = sizeof...(B);
	}
	int a;
};

using xxx = FF<int(int, int, int)>;
xxx ddd{};


template <typename> class Foo2;

template <typename A, typename B>
class Foo2<void(A, B)> {
};
template <typename A, typename B, typename C>
class Foo2<void(A, B, C)> {
};

#define DefineX(name) cout<<23.name<<endl;

void call(int a)
{
	std::cout << "hello" << endl;
}

void my_func(int) { /* ... */ }

struct my_class {
	void my_member(int) { /* ... */ }
};


class Student
{
public:
	void SayHello(int b)
	{
		cout << "hello" << endl;
	}
};

typedef void(*FunctionPointer)(int);
typedef void (Student::*FunctionPointer2)(int);

void nihao(int a)
{
	int bb = a + 1;
}

using proto_fn_type = int(string, int&&...);
proto_fn_type* _caller;


int main()
{
	_caller = [](string a, int&&...)->int {
		string b = a;
		cout << "hello" << endl;
		return 321;
	};

	int xdd = _caller("hello", 2);

	
	FunctionPointer p = nihao;
	p(3);

	Student s;
	FunctionPointer2 p2 = &(Student::SayHello);
	
	(s.*p2)(3);


	FF<int(int, int)> aaa{
		aaa.a = 3
	};

	Foo2<void(int, int)> f2{};
	Foo2<void(int, int, std::string)> f3;


	Foo<int, int> aa{
		aa.a_ = 3,
		aa.b_ = 4,
	};

	int(*fun)(double, int);
	fun = [](double a, int b) {
		cout << a << endl;
		cout << b << endl;
		return 12;
	};

	int x = fun(34, 123);

	std::cin.get();
	return 0;
}

函数指针延伸,委托类:
在这里插入图片描述

#include <iostream>
#include <iomanip>
#include <string>
#include "Test.h"

using namespace std;
template<typename>
class XDelegate;
template<typename Ret, typename ...Args>
class XDelegate<Ret(Args...)>
{
	using proto_fn_type = Ret(void*);
public:

	Ret operator()()
	{
		return _caller(_this);
	}
	template<auto method, typename Type>
	void connect(Type* instance) noexcept
	{
		_this = instance;

		_caller = [](void* data)->Ret
		{
			Type* payload = static_cast<Type*>(data);
			return Ret(std::invoke(method, payload));
		};
	}
private:
	proto_fn_type* _caller;
	void* _this;
};

int f(int* a)
{
	return *a;
}
int main()
{
	XDelegate<int(int)> b{};
	int p = 12345;
	b.connect<&f, int>(&p);
	int a = b();
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值