4

我正在开发一个 irc 机器人来帮助我学习 c++,我想知道是否可以将方法用作这样的变量:

//Irc.h
public:

void *onJoin(char* sender, char* channel);
/////

//Main.cpp
void join(char* sender, char* channel)
{
    cout << sender << endl;
    cout << channel << endl;
}
int main()
{
    Irc irc(stuff);
    irc.onJoin = join;
}
4

4 回答 4

8

对的,这是可能的。这些变量称为函数指针。可以这样写:

void onJoin( char* sender, char * channel );

int main(void)
{
    void (*func)(char *,char *);
    func = &onJoin;
    func( "sender", "channel" );
}

或者,您可以使用std::function<>它。除了第一行main()替换为

    std::function<void(char*,char*)> func;

在我看来,这更清晰一些。如果你使用这个,那么不要忘记添加

#include <functional>

到文件的顶部。除了在函数中使用这些变量,您还可以将它们用作任何structor的成员变量class

于 2013-06-05T15:56:20.900 回答
4

您需要一个指向函数的指针:

void* (*OnJoinFn)(char*, char*);

在你的Irc课堂上,

class Irc
{
public:
  OnJoinFn onJoin;
};

这可以像您在上面所做的那样分配:

int main()
{
    Irc irc(stuff);
    irc.onJoin = join;
}

但我想知道,如果你只是学习 C++,你真的需要一个指向函数的指针吗?指向函数的指针当然是合法且有效的,但它是一个不寻常的实体,我通常希望使用其他一些机制。首先,我建议研究抽象基类:

class IIrc
{
public:
  virtual void* OnJoin(const char*, const char*) = 0;  // pure virtual
  virtual ~IIrc() {}; // Don't forget to implement a virtual destructor in any ABC
};

class MyIrc 
:
  public IIrc
{
public:
  void* OnJoin(const char* sender, const char* channel*)
  {
    // YOUR CODE HERE
  }
};

int main()
{
  IIrc* irc = new MyIrc;
  irc->OnJoin (...);
}

我冒昧地在OnJoin.

您还应该考虑不返回 a void*,它绕过了大多数 C++ 的类型安全机制,而是一个指向实际对象或另一个接口的指针。

最后,使用new(and delete,这里缺少,导致内存泄漏) 是不好的做法。相反,更喜欢在堆栈上分配东西,或者,如果您真的需要动态分配,请使用智能指针。

于 2013-06-05T16:03:10.413 回答
1

虽然这是可能的,但如果您需要这样做,我建议您很可能做错了什么。“我们需要在不同情况下以不同方式执行此操作”的典型 C++ 方法是使用继承:

在 irc.h 中:

   class ircBase
   {
     public:
      ... 
      virtual void onJoin(char *sender, char *channel) = 0;

   };

在 ircXX.h 中:

   class ircXX: public ircBase
   {
     public:
      ... 
       virtual void onJoin(char *sender, char *channel)
       {
          cout << sender << endl;
          cout << channel << endl;
       }

   };

在 ircYY.h 中:

   class ircYY: public ircBase
   {
     public:
      ... 
       virtual void onJoin(char *sender, char *channel)
       {
           ... do something else ... 
       }

   };

然后你创建一个适合你需要的对象。

于 2013-06-05T16:02:55.737 回答
0

您正在寻找的是一个函数指针:

class Irc
{
    public:
        void (*on_join)(char*, char*);
    //  ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
};

void join(char*, char*);

int main()
{
    Irc irc(stuff);
    irc.on_join = join;
}

或者,您可以使用std::function这样您就可以传递捕获/非捕获 lambda:

#include <functional>

class Irc
{
    public:
        std::function<void (char*, char*)> on_join;
    //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
};

int main()
{
    Irc irc(stuff);
    irc.on_join = [] (char* sender, char* channel)
    {
        std::cout << sender  << std::endl;
        std::cout << channel << std::endl;
    };
}
于 2013-06-05T23:46:26.640 回答