我想在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'
答案 0 :(得分:1)
这里要知道的是,指向成员函数的指针不与指向(独立)函数的指针相同。不同之处在于所有成员函数都有一个隐藏的第一个参数,它是函数中的this
指针。因此,您需要有一个对象实例才能实际调用成员函数指针。
只有static
个成员函数没有这个隐藏的第一个参数,因为它们没有this
指针(静态成员函数适用于整个类,不适用于特定实例)和所以可以用作普通函数指针。
使用成员函数指针有三种方法。
第一个是使用静态成员函数,并且有一个参数,它将是一个指向实例的指针。这当然只有在系统允许您将额外的参数传递给函数指针时才有效。如果(我只在这里猜测)wait_event
的第二个参数就是这样一个“userdata”指针,那么这可以用于它:
wait_event(&staticTouched, this);
然后你创建一个调用真实函数的静态成员函数:
static void staticTouched(void* instance)
{
static_cast<UncouplerController*>(instance)->touched();
}
第二种方法是wait_event
是你的类的成员,在这种情况下,它在调用成员函数时实际上可以使用自己的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
函数是Orbit中Lightness Races指出的函数,则不能使用成员函数指针。然而,上面列表中的第一个案例是错误的,因为第二个论点完全不同。
答案 1 :(得分:0)
我同意约阿希姆的观点。另一方面,我会给你一些代码提示,让我知道是否适合你。
更改行:
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)'
因此,您可以重新定义触摸,以便返回指向独立函数的指针,并使用参数更改它的行为。或者,将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;
答案 2 :(得分:0)
这是我的代码,它有效。
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;
我想知道如果没有使用静态成员或函数,并将它们全部移出课堂,我可以得到相同的结果!谁有人告诉我哪种方式更好?谢谢你的帮助。