PDA

View Full Version : Help implement an array of member functions ( member function pointers)?



shawnlau
4th July 2018, 03:27
I'm working a on a program and what it does when the mouse is dragged or clicked will depend on what mode it is in.

This is a simplified version of how I would like it to work, but this is giving me all sorts of errors, starting with errors in cstdlib and into cmath.

Is there a way to do this?

.pro :


TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += \
main.c


main.c


#include <stdio.h>
#include<iostream>

using namespace std;


class MyClass{
public:
static const int SCREAM = 0,WHISPER = 1,SLEEP = 2;
void emote();

private:
typedef void(MyClass::*reaction)();
reaction react[3]= {&MyClass::scream,&MyClass::whisper,&MyClass::sleep};
void scream();
void whisper();
void sleep();

};

void MyClass::scream(){
cout << "eeeeek"<< endl;
}
void MyClass::whisper(){
cout << "ssshhhhhhh"<< endl;
}
void MyClass::sleep(){
cout << "zzzzZZZZZ"<< endl;
}
void MyClass::emote(){
react[SCREAM]();
react[WHISPER]();
react[SLEEP]();
}
int main()
{
MyClass c;
c.emote();

}

d_stranz
4th July 2018, 05:58
There is nothing in the code you posted that would cause errors arising in cstdlib or cmath. You don't even use anything from cmath in the code posted. You've likely "simplified" it a little too much.

shawnlau
4th July 2018, 13:07
I started a new project and pasted the above code into the .pro file and main.cpp file

I now get these errors:

Y:\QTProjects\TestFunctionPtrArray\main.cpp:31: error: must use '.*' or '->*' to call pointer-to-member function in '((MyClass*)this)->MyClass::react[0] (...)', e.g. '(... ->* ((MyClass*)this)->MyClass::react[0]) (...)'
react[SCREAM]();
Y:\QTProjects\TestFunctionPtrArray\main.cpp:32: error: must use '.*' or '->*' to call pointer-to-member function in '((MyClass*)this)->MyClass::react[1] (...)', e.g. '(... ->* ((MyClass*)this)->MyClass::react[1]) (...)'
react[WHISPER]();
Y:\QTProjects\TestFunctionPtrArray\main.cpp:33: error: must use '.*' or '->*' to call pointer-to-member function in '((MyClass*)this)->MyClass::react[2] (...)', e.g. '(... ->* ((MyClass*)this)->MyClass::react[2]) (...)'
react[SLEEP]();

Added after 13 minutes:

I posted on another c++ forum and they suggested I make the functions static and change the typedef to




private:
typedef void(*reaction)();
reaction react[3]= {&MyClass::scream,&MyClass::whisper,&MyClass::sleep};
static void scream();
static void whisper();
static void sleep();

};



Doing this and it works as expected.

shawnlau
4th July 2018, 15:20
There is nothing in the code you posted that would cause errors arising in cstdlib or cmath. You don't even use anything from cmath in the code posted. You've likely "simplified" it a little too much.

I see what happened that created all those weird errors. When I started the project, I started it a non qt C project. It should have been a C++ project. See the :


#include <stdio.h>
#include<iostream>


The MSVC2017 kit didn't point out this error. and the errors I was getting were like this:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\in clude\cstdlib:19: error: C2061: syntax error: identifier 'noexcept'
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\in clude\cstdlib:19: error: C2059: syntax error: ';'
etc.

When I deleted the build folder and reconfigured the project to use the MinGW 32bit kit, it pointed out right away it could not find the <iostream>. Thats when I noticed the mistake.

shawnlau
4th July 2018, 19:13
I ran into some problems making functions static in my real program as they were trying to call non static functions.

So in the the simplified version, this way allows me to make the array and keep the functions non-static;


#include<iostream>
#include <functional>
#include <string>
using namespace std;


class MyClass{
public:
static const int SCREAM = 0,WHISPER = 1,SLEEP = 2;
void emote();

private:

std::function<bool(MyClass*,string) > react[3]= {&MyClass::scream,&MyClass::whisper,&MyClass::sleep};
bool scream(string s);
bool whisper(string s);
bool sleep(string s);

};

bool MyClass::scream(string s){
cout << s << endl;
return true;
}
bool MyClass::whisper(string s){
cout << s << endl;
return false;
}
bool MyClass::sleep(string s){
cout << s << endl;
return true;
}
void MyClass::emote(){
bool a,b,c;
a =react[SCREAM](this,"eeek");
b = react[WHISPER](this,"shhh");
c = react[SLEEP](this, "zzzz");
cout<< a << " " << b << " "<< c<<endl;
}
int main()
{
MyClass c;
c.emote();

}