2013-06-05 24 views
4

我工作的一个IRC bot,以此来帮助我学习C++,我想知道是否有可能使用的方法是这样的变量:使用方法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

阅读有关['的std :: function'](http://en.cppreference.com/w/cpp/utility/functional/function)和['的std :: bind'](http://en.cppreference.com/w/cpp /实用程序/功能/绑定)。也有[提升](http://www.boost.org/doc/libs/1_53_0/doc/html/function.html)[变体](http://www.boost.org/doc/libs/1_53_0 /libs/bind/bind.html)。 –

回答

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> 

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

+0

对于第一个版本,您可以只写'auto func =&onJoin'。 – Appleshell

+0

函数使用'typedef'或'auto',否则他们只会感到困惑。 –

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 ... 
     } 

    }; 

然后你创建你所需要的正确类型的对象。

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引入const正确性的自由。

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

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

+0

好吧,我重新学习C++。另外我知道我可以使用继承irc类的类,但我想我会尝试新的东西。 –

+0

够公平的。这里是你如何使用指向函数的指针。 –

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; 
    }; 
}