2013-06-05 28 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; 
    }; 
}