【问题标题】:C++ method pointer arrayC++ 方法指针数组
【发布时间】: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);
                                        ^
  1. 我不知道把 * 放在哪里,我也不知道为什么这里需要取消引用。据我所知,对于 C 语言,调用函数指针时不需要这样做。 我读过它应该类似于(this->*temp.set_func)(value);,但我怎样才能使这种语法适应我的问题? myInstance 不是该类的成员,所以我没有this。另外, myInstance 不是指针,所以我不明白为什么 * 应该是必要的。有人可以帮我吗?
  2. 当我像 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


【解决方案1】:

感谢评论部分的 Igor Tandetnik,我现在可以发布问题 1 的答案:

MyClass myInstance(10);
MyClass::myPtr function = myInstance.ptrSingle;
MyClass::myPtr functionFromArray = myInstance.ptrArray[1];

int ret1 = (myInstance.*function)(1);
int ret2 = (myInstance.*(myInstance.ptrArray[0]))(1);
int ret3 = (myInstance.*(myInstance.ptrArray[1]))(1);
int ret4 = (myInstance.*functionFromArray)(1);

我的错误是假设方法指针直接指向实例的方法。 Ans 由于 ret2 和 3 的行看起来很丑,我添加了一个关于如何访问数组的示例。也许这对其他人有用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 2020-02-16
    相关资源
    最近更新 更多