【问题标题】:C++ Pointer to function call not in scopeC++ 指向函数调用的指针不在范围内
【发布时间】:2014-05-31 22:37:01
【问题描述】:

在过去的 3 个小时里,我一直在试图找出我做错了什么。我只是需要一些其他的眼睛,我已经尝试了我能想到的一切,甚至是各种随机排列,试图让编译器告诉我一些有用的东西。

这是我现在的位置:

代码:

class villain
{
public:
   villain();
   //lots of other stuff
   bool Type1EnemyBlasts();
   bool Type2EnemyBlasts();
   bool (villain::*OnFire)();
};

villain::villain()
{
    //lots of other stuff
    OnFire = &villain::Type1EnemyBlasts;
}

main
{
    //lots and lots of other stuff
    villain *targets[100];
    targets[0] = new villain();
    if(targets[0]->*OnFire() == true)
    {
         //do stuff
    }
}

当我调用“targets[0]->*OnFire()”时发生错误,它声明它未在此范围内声明。当我在反派构造器内部定义“OnFire”时,我必须用“&villain::”来定义它,这让我感觉很奇怪,但我发现的所有信息都表明它必须以这种方式完成,而且确实会搅动起来如果我尝试其他方式,则会出现大量错误。

调用属于targets[0]的*OnFire()指针的正确语法是什么?

【问题讨论】:

  • 不需要使用解引用操作符,直接调用targets[0]->OnFire()
  • @wiily 这对于普通指针来说很好,但对于指向成员的指针则不然。
  • 为什么要声明一个数组指针?声明一个数组已经意味着你声明了一个指向它的第一个元素的指针。
  • 如果烦人的话,所需的语法至少是完全明确的。
  • @meross 这是一个指针数组。并且数组不是指针,即使它可以衰减为一个。

标签: c++ pointers reference scope function-pointers


【解决方案1】:

没有“正确的语法”。这将是残酷的(见下文)

改用std::function

#include <functional>

struct villain
{
    villain();
    //lots of other stuff
    bool Type1EnemyBlasts() {return true;}
    bool Type2EnemyBlasts() {return false;}
    std::function<bool(villain&)> OnFire;
};

villain::villain()
{
    OnFire = &villain::Type1EnemyBlasts;
}

int main()
{
    villain *targets[100];
    targets[0] = new villain();
    villain& v = *targets[0];

    if (v.OnFire(v))
    {
        return 1;
    }

    return 0;
}

与指向成员函数的方法对比:

struct villain
{
    villain();
    //lots of other stuff
    bool Type1EnemyBlasts() {return true;}
    bool Type2EnemyBlasts() {return false;}
    bool (villain::*OnFire)();
};

villain::villain()
{
    //lots of other stuff
    OnFire = &villain::Type1EnemyBlasts;
}

int main()
{
    //lots and lots of other stuff
    villain *targets[100];
    targets[0] = new villain();
    villain& v = *targets[0];

    if ((v.*v.OnFire)())
    {
        return 1;
    }

    return 0;
}

【讨论】:

  • @AlanStokes 看来我不明白你想说什么。 FWIW,我测试了我所有的代码:/
  • 啊,对不起,误读了你在做什么。错误完全是我的。
  • 我觉得很奇怪你在调用OnFire 时仍然必须再次传递v 为什么不直接使用function&lt;bool(void)&gt; 并分配它bind(&amp;villain::Type1EnemyBlasts, this)
  • 第一个例子返回错误“'function' in namespace 'std' does not name a type”
  • 第二个例子返回ptmf没有命名类型,ptmf没有在这个范围内声明
【解决方案2】:

改变

if(targets[0]->*OnFire() == true)

if((targets[0]->*(targets[0]->OnFire))() == true)

由于函数调用运算符()的优先级高于-&gt;*,因此第一种形式被解释为:

if(targets[0]->*(OnFire()) == true)

如您所见,这不是您想要的。

【讨论】:

  • 试过这个,不幸的是返回了同样的错误。
【解决方案3】:

调用指向成员函数的指针的语法相当糟糕。这是正确的语法:

if ((targets[0]->*(targets[0]->OnFire))() == true)

这简直是丑陋的。这就是Parashift C++ FAQ page on calling pointers to member functions 建议为此目的定义宏的原因——请注意,这些页面的作者不喜欢宏。

#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

...

 if (CALL_MEMBER_FN(*targets[0],targets[0]->OnFire)() == true)

如 sehe 的回答中所述,使用宏或使用 std::function

【讨论】:

  • 圣钼它编译。它可能很丑,但它有效。非常感谢!
  • @user3542913 让我给你一些父亲的建议。当您想编写这样的代码时:不要这样做。并且:不要使用邪恶的宏来消除痛苦。我的回答显示了这个的可读版本:if ((v.*ptmf)())...
  • 嗯,除非您在下面更改了答案,而且我还没有机会尝试新版本。旧版本对我不起作用。
  • @sehe,有很多 C++ 项目永远停留在 C++03 领域,不允许使用 Boost。在那个世界中调用指向成员函数的指针是很困难的。正确的语法非常丑陋(我前面已经说过了!)宏不是一个糟糕的选择。
  • @大卫std::function is part of TR1。是的,即使没有 as my answer shows - Live On Coliru(纯 c++03,没有 TR1),宏仍然不需要。
【解决方案4】:

尝试: (targets[0]-&gt;*OnFire)()

这里有一些关于函数指针的重要信息:http://www.newty.de/fpt/fpt.html#defi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-26
    • 2012-02-11
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    相关资源
    最近更新 更多