如何使用指向C++方法的指针
How can I use pointer to C++ method?
我想在wake_event中使用类方法指针,如下所示,但是编译错误,我不想使用静态成员和方法,因为此类可能有多个实例,可以吗? 我可以修改我的源吗?
class UncouplerController {
private:
TouchSensor *touchSensor;
public:
wakeup_t touched(wakeup_t data) {
return UncouplerController::touchSensor->pressed();
}
const void uncoupling() {
wait_event(&touched, 0);
}
}
编译错误如下
/usr/local/bin/h8300-hitachi-hms-g++ -DCXX -fno-rtti -fno-exceptions -O2 -fno-builtin -fomit-frame-pointer -Wall -I/brickos/include -I/brickos/include/lnp -I. -I/brickos/boot -c rcx1.C -o rcx1.o
In file included from rcx1.H:27,
from rcx1.C:21:
UncouplerController.H: In function `static wakeup_t UncouplerController::untouched(long unsigned int)':
UncouplerController.H:38: member `UncouplerController::touchSensor' is non-static but referenced as a static member
UncouplerController.H:62: at this point in file
UncouplerController.H:63: warning: control reaches end of non-void function `UncouplerController::untouched(long unsigned int)'
UncouplerController.H: In method `const void UncouplerController::uncoupling()':
UncouplerController.H:74: converting from `wakeup_t (UncouplerController::*)(long unsigned int)' to `wakeup_t (*)(long unsigned int)'
UncouplerController.H: In method `const void UncouplerController::coupling()':
UncouplerController.H:99: converting from `wakeup_t (UncouplerController::*)(long unsigned int)' to `wakeup_t (*)(long unsigned int)'
UncouplerController.H: At top level:
UncouplerController.H:112: `class TouchSensor * UncouplerController::touchSensor' is not a static member of `class UncouplerController'
这里要知道的是,指向成员函数的指针与指向(独立)函数的指针不同。不同之处在于,所有成员函数都有一个隐藏的第一个参数,该参数是函数中的this
指针。因此,您需要有一个对象的实例才能实际调用成员函数指针。
只有static
成员函数没有这个隐藏的第一个参数,因为它们没有this
指针(静态成员函数用于整个类,而不是特定实例),因此可以用作普通函数指针。
有三种使用成员函数指针的方法。
-
第一种是使用静态成员函数,并为其提供一个参数,该参数将作为指向实例的指针。当然,这只有在系统允许您将额外的参数传递给函数指针时才有效。如果(我只是在这里猜测)
wait_event
的第二个参数是这样的"userdata"指针,那么这可以用于它:wait_event(&staticTouched, this);
然后你创建一个静态成员函数来调用真正的函数:
static void staticTouched(void* instance) { static_cast<UncouplerController*>(instance)->touched(); }
-
第二种方法是,如果
wait_event
是类的成员,在这种情况下,它在调用 member 函数时实际上可以使用自己的this
指针:void wait_event(void (UncouplerController::*func)(), ...) { // Do stuff... (this->func)(); // Call the member function pointer }
-
第三种方法是使用新的 C++11
std::function
类,而不是成员函数指针。这将使事件处理系统更加通用,因为std::function
可用于存储普通函数、静态成员函数、非静态成员函数和 lambda 表达式。除此之外,它与第二种情况非常相似:void wait_event(std::function<void()> func, ...) { // Do stuff... func(); // Call the function object }
然后,要使用成员函数指针调用
wait_event
,请使用std::bind
:wait_event(std::bind(&UncouplerController::touched, this), 0);
如果wait_event
函数是轨道中的轻量级竞赛所指出的函数,则不能使用成员函数指针。我上面列表中的第一种情况是错误的,因为第二个参数是完全不同的东西。
这是我的代码,它可以工作。
class UncouplerController {
private:
static TouchSensor *touchSensor;
public:
UncouplerController(Sensor::Port sensorPort) {
touchSensor = new TouchSensor(sensorPort);
}
~UncouplerController() {
delete touchSensor;
}
static wakeup_t touched(wakeup_t data) {
return UncouplerController::touchSensor->pressed();
}
static wakeup_t untouched(wakeup_t data) {
return !UncouplerController::touchSensor->pressed();
}
const void uncoupling() {
wait_event(&UncouplerController::touched, 0);
delay(UNCOUPLING_TIME1);
}
const void coupling() {
wait_event(&UncouplerController::touched, 0);
wait_event(&UncouplerController::untouched, 0);
delay(COUPLING_TIME);
}
};
TouchSensor *UncouplerController::touchSensor;
我想知道如果没有使用静态成员或函数,并将它们全部移出类,我可以得到相同的结果!! 有人告诉我哪种方式更好吗? 感谢您的帮助。
我同意约阿希姆的观点。另一方面,我会给你一些代码的提示,让我知道是否适合你。
更改行:
return UncouplerController::touchSensor->pressed();
由:
return this->touchSensor->pressed();
wait_event正在检查一个独立函数,您正在传递一个作为类成员的函数,这就是为什么输出错误中的以下行
:UncouplerController.H:74: converting from `wakeup_t (UncouplerController::*)(long unsigned int)' to `wakeup_t (*)(long unsigned int)'
因此,您可以重新定义 touched 以返回一些指向独立函数的指针,并使用参数更改其行为。或者,将wakeup_t声明为独立函数,并使其成为类的好友。第二个看起来要容易得多。
让我知道是否有效。如果您发布更多代码,也许可以帮助您更多。
另一种方法是使用关键字"reinterpret_cast",但我不推荐它。
好吧,您可以尝试以下方法:
// Define the type expected by "wait_event"
typedef wakeup_t (*wake_func_ptr) (wakeup_t data);
class UncouplerController {
private:
TouchSensor *touchSensor;
public:
// Member for pointing the target functions.
wake_func_ptr touched;
wake_func_ptr untouched;
UncouplerController(Sensor::Port sensorPort)
{
// This will rise a lot of warnings.
// I strongly not recomend to do this.
// But it seems to be a solution.
touched = reinterpret_cast<wake_func_ptr>(&UncouplerController::touched_func);
untouched = reinterpret_cast<wake_func_ptr>(&UncouplerController::untouched_func);
touchSensor = new TouchSensor(sensorPort);
}
~UncouplerController() {
delete touchSensor;
}
wakeup_t touched_func(wakeup_t data) {
return touchSensor->pressed();
}
wakeup_t untouched_func(wakeup_t data) {
return touchSensor->pressed();
}
const void uncoupling() {
wait_event(touched, 0);
delay(UNCOUPLING_TIME1);
}
const void coupling() {
wait_event(touched, 0);
wait_event(untouched, 0);
delay(COUPLING_TIME);
}
};
// The purpose of this line isn't clear for me.
TouchSensor *UncouplerController::touchSensor;
- 将一个类的方法指针存储到另一个类中
- 如何调用返回类方法指针的类方法
- 通过reinterpret_casting方法指针从指针调用派生类的方法。这是 UB 吗?
- 泛型方法指针.reinterpret_cast指向不同类的方法指针,这是 UB 吗?
- C++;类方法指针;λ;将 lambda 作为成员函数指针传递;
- 使用模板、方法指针和字符串键入推导
- 将方法指针作为整数参数发送到C#的C 方法
- 从C 中的VTable获取方法指针
- 模板化方法指针 - 无法匹配函数参数的指针
- 获取特定的模板重载方法指针
- 如何将方法指针声明为Typedef方法参数
- 如何将方法指针类型转换为函数指针类型
- 如何在使用 pthreads 时将方法指针作为函数参数传递C++
- 方法指针映射,编译器说他们不接受任何参数
- C# 方法指针,如 C++ 中的指针
- c++创建新的LinkedList类:Clear()方法指针被释放未分配
- 尝试获取类方法指针时出现E_NOINTERFACE
- 传递和强制转换方法指针
- 常量方法指针的类型是什么
- 将对象的方法指针传递给接受 [静态方法指针/全局函数] 指针的函数