c++ | this指针 和bind、function

文章讲述了C++中成员函数特有的this指针与C函数指针的差异,强调了成员函数不能直接传递给C函数指针的原因,并介绍了处理方法,如静态成员函数、Lambda表达式和std::function。

个人理解:
this 指针 可以简单理解为类 对象的 指针(也是隐藏指针),注意,类的成员(成员函数、成员变量)是通过类的对象进行调用的。如果把函数充当成员函数是错误的,粗鲁的解释,类的成员函数都有一个隐藏的指针(this指针),但是 c函数是没有指针的。

看看gpt的回答
C++的成员函数和C函数在底层上有一些重要的区别,这就是为什么不能直接将成员函数指针传递给期望C函数指针的地方。这些区别涉及到成员函数的隐含参数(即this指针)和调用约定。

在C++中,成员函数可以访问其所属类的成员变量和其他成员函数。为了实现这种功能,每个成员函数都有一个隐含的额外参数,称为this指针,该指针指向调用该函数的对象实例。这就是成员函数可以访问类成员的原因。而普通的C函数没有这个隐含的this指针。

C函数指针只是一个指向函数的指针,它没有额外的信息来处理成员函数的this指针。因此,直接将成员函数指针传递给C函数指针是不合适的,因为C函数指针无法处理这个额外的this指针。

为了在C++中使用成员函数,可以使用以下方法之一:

静态成员函数:静态成员函数没有隐含的this指针,因此它们可以被转换为普通的C函数指针。但是,静态成员函数只能访问静态成员变量,无法访问非静态成员变量。

Lambda表达式:使用Lambda表达式可以捕获当前作用域中的变量,并将其与函数一起封装。这使得Lambda可以作为函数对象传递,并在其中调用成员函数。

std::function和std::bind:这些C++标准库的功能提供了更灵活的方式来处理函数对象,包括成员函数。

如果你想将成员函数传递给C函数指针,需要首先考虑如何处理隐含的this指针,例如将成员函数包装在静态成员函数中,或使用Lambda表达式和std::function。

C++11 引入的 `std::function` `std::bind` 为现代 C++ 编程带来了极大便利。`std::function` 允许统一存储操作不同类型的可调用对象,简化代码结构;`std::bind` 则能灵活调整函数参数调用方式,提高代码的可读性可维护性 [^1]。 ### std::function `std::function` 是一个通用的多态函数包装器,它可以存储、复制调用任何可调用对象,包括函数函数指针、成员函数指针、仿函数、lambda 表达式等。其使用方法是在模板参数中指定可调用对象的签名,然后用它来存储对应的可调用对象。 以下是一个简单的示例: ```cpp #include <iostream> #include <functional> // 普通函数 int add(int a, int b) { return a + b; } int main() { // 定义一个 function 对象,它可以存储返回值为 int,参数为两个 int 的可调用对象 std::function<int(int, int)> func = add; std::cout << func(1, 2) << std::endl; return 0; } ``` `std::function` 的原理是它内部维护了一个类型擦除机制,通过虚函数表来调用存储的可调用对象,从而实现了对不同类型可调用对象的统一存储调用。 ### std::bind `std::bind` 用于创建一个新的可调用对象,它可以调整原可调用对象的参数绑定调用方式。可以绑定普通函数,也可以绑定成员函数。在绑定参数时,可以使用 `std::placeholders` 来占位,表示在调用新的可调用对象时再传入这些参数。 以下是绑定普通函数成员函数的示例: ```cpp #include <iostream> #include <functional> // 普通函数 int add(int x, int y) { return x + y; } // 成员函数 class ADD { public: int add(int x, int y) { return x + y; } }; int main() { ADD obj; // 绑定普通函数返回函数对象 auto f1 = std::bind(add, std::placeholders::_1, 2); // 绑定成员函数返回函数对象 auto f2 = std::bind(&ADD::add, &obj, 2, std::placeholders::_1); std::cout << f1(1) << std::endl; std::cout << f2(1) << std::endl; return 0; } ``` `std::bind` 的原理是它会生成一个新的可调用对象,这个新对象内部保存了原可调用对象绑定的参数,当调用新对象时,会根据绑定的参数占位符将参数传递给原可调用对象进行调用。 ### 二者结合使用 由于 `std::bind` 可以包装可调用对象并返回可调用对象,而 `std::function` 也能包装可调用对象,所以 `std::function` 可以包装 `std::bind` 生成的对象 [^3]。 以下是结合使用的示例: ```cpp #include <iostream> #include <functional> int add(int a, int b) { return a + b; } int main() { auto bindObj = std::bind(add, std::placeholders::_1, 2); std::function<int(int)> func = bindObj; std::cout << func(3) << std::endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值