【发布时间】:2015-08-23 12:41:19
【问题描述】:
我有一个有几种方法的类。现在我想让这个类有一个方法指针数组,可以用该类的实例调用。
基本上是这样的
class MyClass
{
public:
MyClass(int aInit);
typedef int (MyClass::*myPtr)(int);
const myPtr ptrArray[2];
const myPtr ptrSingle;
int plus(int b);
int minus(int b);
private:
int a;
};
使用如下实现:
MyClass::MyClass(int aInit) :
ptrArray({&MyClass::plus, &MyClass::minus}),
ptrSingle(&MyClass::plus)
{
this->a = aInit;
}
int MyClass::plus(int b)
{
return (this->a + b);
}
int MyClass::minus(int b)
{
return (this->a - b);
}
在另一个类中,我有这个使用 MyClass 的方法,我在其中尝试访问函数指针成员:
MyClass myInstance(10);
MyClass::myPtr function = myInstance.ptrSingle;
int ret1 = function(1);
int ret2 = myInstance.ptrArray[0](1);
int ret3 = myInstance.ptrArray[1](1);
这会导致以下错误消息:
error: must use '.*' or '->*' to call pointer-to-member function in 'function (...)', e.g. '(... ->* function) (...)'
int ret1 = function(1);
^
error: must use '.*' or '->*' to call pointer-to-member function in 'myInstance.MyClass::ptrArray[0] (...)', e.g. '(... ->* myInstance.MyClass::ptrArray[0]) (...)'
int ret2 = *(myInstance.ptrArray[0])(1);
^
error: must use '.*' or '->*' to call pointer-to-member function in 'myInstance.MyClass::ptrArray[1] (...)', e.g. '(... ->* myInstance.MyClass::ptrArray[1]) (...)'
int ret3 = myInstance.ptrArray[1](1);
^
- 我不知道把 * 放在哪里,我也不知道为什么这里需要取消引用。据我所知,对于 C 语言,调用函数指针时不需要这样做。
我读过它应该类似于
(this->*temp.set_func)(value);,但我怎样才能使这种语法适应我的问题? myInstance 不是该类的成员,所以我没有this。另外, myInstance 不是指针,所以我不明白为什么 * 应该是必要的。有人可以帮我吗? - 当我像
const myPtr ptrArray[] = {&MyClass::plus, &MyClass::minus};这样初始化 myPtr 时,编译器会报错too many initializers for 'int (MyClass::* const [0])(int)'。但是对于非 int 类型的这种初始化不应该在 c++11 中实现吗?
我正在使用 gcc (Gentoo 4.9.3 p1.0, pie-0.6.2) 4.9.3 和 c++11。
【问题讨论】:
-
那些指向成员的指针不绑定到类的特定实例。如果你有
MyClass a, b;,你会发现a.ptrSingle == b.ptrSingle。所以当你想通过这样的指针调用成员时,你仍然需要提供一个对象来调用它:(myInstance.*function)(1) -
With C, as far as I remember, this should not be necessary when calling a function pointer.在 C++ 中也没有必要。但是您没有使用普通函数指针 - 您正在使用指向成员函数的指针。我想你不会感到惊讶,你不能只调用plus(1),而是必须写myInstance,plus(1)——为了调用非静态成员函数,你需要提供一个对象来调用它。无论您是通过名称直接引用成员,还是通过指针间接引用,这同样适用。 -
myInstance is not a pointer, so I don't see why * should be necessary在该表达式中没有*。.*是单个运算符,而不是“一个句点后跟一个星号”,就像>>是单个运算符而不是“连续两个大于运算符”一样。->*也一样——它是一个不可分割的标记。 -
对于#2,clang 给出了更好的错误信息:
error: array bound cannot be deduced from an in-class initializer。您只需要明确指定数组绑定,如const myPtr ptrArray[2] = {&MyClass::plus, &MyClass::minus}; -
感谢您的所有 cmets。很高兴知道,根本不可能忽略数组大小。但是对于
int ret1 = (myInstance.*ptrSingle)(1);,我只会收到一条不同的错误消息:'ptrSingle' was not declared in this scope@Igor Tandetnik
标签: arrays pointers c++11 methods