Using a method as a variable in C ++

I am working on the irc bot to help me learn C ++, and I was wondering if the method can be used as a variable like this:

//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
source share
4 answers

Yes it is possible. These variables are called function pointers. Can write it like this:

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

Alternatively, you can use std::function<> for this. The code will be the same, except for the first line in main() , which is replaced by

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

This, in my opinion, is a little picky. If you use this, be sure to add

 #include <functional> 

to the beginning of the file. Instead of using such variables in functions, you can also use them as member variables of any struct or class .

+8
source

You need a function pointer:

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

In your class Irc

 class Irc { public: OnJoinFn onJoin; }; 

This can be assigned as you do above:

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

But I am wondering if you are just learning C ++, do you really need a function pointer? function pointers are legally legal and valid, but an unusual object, and I usually expect to use some other mechanism. In the beginning, I would suggest looking at abstract base classes:

 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 (...); } 

I allowed to introduce const correctness in OnJoin .

You should also consider returning void* , which bypasses most security mechanisms like C ++, but a pointer to the actual object or other interface.

Finally, using new (and delete , which is missing here, resulting in a memory leak) is bad practice. Instead, prefer to allocate things on the stack or, if you really need dynamic allocation, use a smart pointer.

+4
source

While this is possible, I would suggest that you are most likely doing something wrong if you need to do this. TYPICAL C ++ The way to do "we need to do it differently in different circumstances" is to use inheritance:

in irc.h:

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

in ircXX.h:

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

in ircYY.h:

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

And then you create the object of the desired type for what you need.

+1
source

What you are looking for is a function pointer:

 class Irc { public: void (*on_join)(char*, char*); // ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ }; void join(char*, char*); int main() { Irc irc(stuff); irc.on_join = join; } 

Alternatively, you can use std::function so that you can pass capture / not capture lambdas:

 #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; }; } 
0
source

Source: https://habr.com/ru/post/1484677/


All Articles