如何用指向成员函数的指针切换?
How to switch with pointer to member functions?
好吧,我只想做一个带有函数指针和方法指针的“switch”。开关是,如果我调用方法 Run()
,它将重定向到 A::RunOn()
或 A::RunOff()
根据 Run
ptr 指向这些成员函数。
我知道可以做到。我用普通 c but I have searched and googled to do the same thing in c++ 做到了,但运气不好。
class A
{
typedef (void)(A::*RunPtr)(int);
RunPtr RunMethod;
public:
RunMethod Run;
A()
{
Run = RunOff;
}
void SetOn(bool value)
{
if (value)
Run = RunOn;
else
Run = RunOff;
}
void RunOn(int)
{
// RunOn stuff here
}
void RunOff(int)
{
// RunOff stuff here
}
};
所以我可以调用 Run()
并且函数调用之间会有一个切换,我认为这比只做更有效率:
if (on)
RunOn();
else
RunOff();
不知道怎么做!
您的成员函数指针 typedef
是错误的(尽管显示的代码中存在其他问题)。你需要
typedef void(A::*RunPtr)(int);
或者你可以在using
keyword的帮助下为classA
的成员函数指针提供别名,如下所示:
using RunPtr = void(A::*)(int);
RunPtr RunMethod;
现在在SetOn
中你可以如下进行成员指针赋值
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}
现在,为了调用存储的成员函数指针,您可以/可以提供一个Run
成员函数,如下所示:
void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}
call to member function is a bit tricky。
但是,这可以使用更通用的 std::invoke
from <functional>
header (Since c++17).
来完成
完整示例如下:
#include <iostream>
#include <functional> // std::invoke
class A
{
using RunPtr = void(A::*)(int);
// or with typedef
// typedef void(A::*RunPtr)(int);
RunPtr RunMethod;
public:
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}
void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}
void RunOn(int arg) { std::cout << "RunOn: " << arg << "\n"; }
void RunOff(int arg) { std::cout << "RunOff: " << arg << "\n"; }
};
int main()
{
A obj;
obj.SetOn(true);
obj.Run(1); // prints: RunOn: 1
obj.SetOn(false);
obj.Run(0); // prints: RunOff: 0
}
一旦你修复了其中的语法错误,你的代码就可以正常工作,即:
Class
需要 class
.
在RunMethod Run;
中,RunMethod
不是类型,是成员变量。您 的意思是 改为使用 RunPtr Run;
(并摆脱 RunMethod
),但这对您来说效果不佳(请参阅下文了解原因)。
在Run = RunOn;
和Run = RunOff;
中,需要对方法名进行全限定,并加上&
运算符作为前缀,如Run = &A::RunOn;
.
尝试以下操作:
class A {
public:
typedef void (A::*RunPtr)(int);
RunPtr Run;
A()
{
Run = &A::RunOff;
}
void SetOn(bool value)
{
if (value)
Run = &A::RunOn;
else
Run = &A::RunOff;
}
void RunOn(int param)
{
//RunOn stuff here
}
void RunOff(int param)
{
//RunOff stuff here
}
};
但是请注意,即使您 可以 使用 Run
作为 public 方法指针,调用者仍然需要使用 operator.*
或 operator->*
实际调用它,这看起来不太好,例如:
A a;
(a.*a.Run)(...);
如果你希望能够像 a.Run(...)
那样调用 Run()
那么你必须使 Run()
成为一个标准方法,并让它在内部使用一个方法指针,例如:
class A {
typedef void (A::*RunPtr)(int);
RunPtr RunMethod;
public:
A()
{
RunMethod = &A::RunOff;
}
void SetOn(bool value)
{
if (value)
RunMethod = &A::RunOn;
else
RunMethod = &A::RunOff;
}
void RunOn(int param)
{
//RunOn stuff here
cout << "RunOn: " << param << endl;
}
void RunOff(int param)
{
//RunOff stuff here
cout << "RunOff: " << param << endl;
}
void Run(int param)
{
(this->*RunMethod)(param);
}
};
A a;
a.Run(...);
好吧,我只想做一个带有函数指针和方法指针的“switch”。开关是,如果我调用方法 Run()
,它将重定向到 A::RunOn()
或 A::RunOff()
根据 Run
ptr 指向这些成员函数。
我知道可以做到。我用普通 c but I have searched and googled to do the same thing in c++ 做到了,但运气不好。
class A
{
typedef (void)(A::*RunPtr)(int);
RunPtr RunMethod;
public:
RunMethod Run;
A()
{
Run = RunOff;
}
void SetOn(bool value)
{
if (value)
Run = RunOn;
else
Run = RunOff;
}
void RunOn(int)
{
// RunOn stuff here
}
void RunOff(int)
{
// RunOff stuff here
}
};
所以我可以调用 Run()
并且函数调用之间会有一个切换,我认为这比只做更有效率:
if (on)
RunOn();
else
RunOff();
不知道怎么做!
您的成员函数指针 typedef
是错误的(尽管显示的代码中存在其他问题)。你需要
typedef void(A::*RunPtr)(int);
或者你可以在using
keyword的帮助下为classA
的成员函数指针提供别名,如下所示:
using RunPtr = void(A::*)(int);
RunPtr RunMethod;
现在在SetOn
中你可以如下进行成员指针赋值
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}
现在,为了调用存储的成员函数指针,您可以/可以提供一个Run
成员函数,如下所示:
void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}
call to member function is a bit tricky。
但是,这可以使用更通用的 std::invoke
from <functional>
header (Since c++17).
完整示例如下:
#include <iostream>
#include <functional> // std::invoke
class A
{
using RunPtr = void(A::*)(int);
// or with typedef
// typedef void(A::*RunPtr)(int);
RunPtr RunMethod;
public:
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}
void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}
void RunOn(int arg) { std::cout << "RunOn: " << arg << "\n"; }
void RunOff(int arg) { std::cout << "RunOff: " << arg << "\n"; }
};
int main()
{
A obj;
obj.SetOn(true);
obj.Run(1); // prints: RunOn: 1
obj.SetOn(false);
obj.Run(0); // prints: RunOff: 0
}
一旦你修复了其中的语法错误,你的代码就可以正常工作,即:
Class
需要class
.在
RunMethod Run;
中,RunMethod
不是类型,是成员变量。您 的意思是 改为使用RunPtr Run;
(并摆脱RunMethod
),但这对您来说效果不佳(请参阅下文了解原因)。在
Run = RunOn;
和Run = RunOff;
中,需要对方法名进行全限定,并加上&
运算符作为前缀,如Run = &A::RunOn;
.
尝试以下操作:
class A {
public:
typedef void (A::*RunPtr)(int);
RunPtr Run;
A()
{
Run = &A::RunOff;
}
void SetOn(bool value)
{
if (value)
Run = &A::RunOn;
else
Run = &A::RunOff;
}
void RunOn(int param)
{
//RunOn stuff here
}
void RunOff(int param)
{
//RunOff stuff here
}
};
但是请注意,即使您 可以 使用 Run
作为 public 方法指针,调用者仍然需要使用 operator.*
或 operator->*
实际调用它,这看起来不太好,例如:
A a;
(a.*a.Run)(...);
如果你希望能够像 a.Run(...)
那样调用 Run()
那么你必须使 Run()
成为一个标准方法,并让它在内部使用一个方法指针,例如:
class A {
typedef void (A::*RunPtr)(int);
RunPtr RunMethod;
public:
A()
{
RunMethod = &A::RunOff;
}
void SetOn(bool value)
{
if (value)
RunMethod = &A::RunOn;
else
RunMethod = &A::RunOff;
}
void RunOn(int param)
{
//RunOn stuff here
cout << "RunOn: " << param << endl;
}
void RunOff(int param)
{
//RunOff stuff here
cout << "RunOff: " << param << endl;
}
void Run(int param)
{
(this->*RunMethod)(param);
}
};
A a;
a.Run(...);