0

I'm trying to send a pointer to a class function as a variable to another class. I'm trying to keep both classes separate so I can reuse the code without having to edit it in the future.

I'm compiling on Windows 7, using Visual Studio 2015.

DATASTRUCT dataItem = {0, 1, 0, 1, dataText, parentClass::doSomething};

childClass.addItem(dataItem); //childClass is initiated as a member of parentClass

Elsewhere:

typedef struct dataStruct{
    double min_x;
    double max_x;
    double min_y;
    double max_y;
    GLTEXT label; //custom struct for text information
    void(*function)(void);
}DATASTRUCT;

I want childClass to be able to go about its business and check for certain parameters, and when childClass is done I want it to call doSomething from parentClass, without actually knowing it's a nested class.

The error I get during compile is:

void(parentClass::)() cannot be used to initialise an entity of void()().

I am able to define a standard function and call that, but that's not unique to each parentClass, and I then have to specify which parentClass::doSomething to which I am referring.

The simplest solution I have found is to redefine the pointer to function in childClass to void(parentClass::*)(), which is exactly what I want, but not how I want it.

With that said, I don't know where to take this, is there another way? Something similar?

Edit:

If possible, how would I explicitly send the information required for my childClass to properly interpret the function pointer dynamically.

So...

childClass.addItem(classInformation, dataItem, &parentClass::doSomething);

Or does the receiving end always have to know "parentClass::" in advance? Would this then be a good time to use void pointers?

Am I chasing after my own tail or is this going somewhere?

Edit:

Something like this seems dangerous, but, here it is.

childClass.addItem(classInformation, dataItem, static_cast<void*>(&parentClass::doSomething));

childClass::callParent(classInformation, void*function){
    static_cast<classInformation.something*>(function)();
}

What would "classInformation.something" be in this case?

3
  • Member funcctions require an object they would operate on. How would you specify which one you want to access in your case? Commented Jan 22, 2016 at 14:34
  • BTW, you really should use &parentClass::doSomething. Only MSVC will forgive you that missed &, and that's only because they try to be bug-compatible with VC++6. Commented Jan 22, 2016 at 15:34
  • @MSalters I'll keep that in mind, I used to add & before my function pointers in c, but I started getting weird errors in c++ for similar pointers. So far I've noticed Visual Studio seems to prefer without. Commented Jan 23, 2016 at 2:50

2 Answers 2

0

Function pointers are really limiting. I would suggest to use std::function<void()> instead. Note that you will still have to tell which object member function would operate upon. You can use std::bind or lambda to do that:

DATASTRUCT dataItem = 
    {0, 1, 0, 1, dataText, std::bind(&parentClass::doSomething, std::ref(someParentClassObject))};
//or
DATASTRUCT dataItem = 
    {0, 1, 0, 1, dataText, [&someParentClassObject](){ someParentClassObject.doSomething(); }};
Sign up to request clarification or add additional context in comments.

1 Comment

Never heard of it before, looked confusing, but I finally had time in front of the computer to try it and it worked no problems using std::function/bind. Not to mention this makes no difference to the function call in line, preserving my desired format. You're a beast. Go have a fantastic day.
0

The problem is that the class member function needs to know where class variables are, which it can't know if all it has to go on is a function pointer to the class function without a reference to the object that it is a member of. So a parentClass::* implicitly has a pointer to the object, whereas a function pointer does not.

Fundamentally, you need to keep track of the object in order to call one of its member functions. You can use a pointer to the object and call the member function from it, or you can use a parentClass::* which does almost the same thing behind the scenes.

Perhaps there is a more basic underlying question that will let you get around this limitation. For example, rather than asking if you can do this, maybe there's a different way you can accomplish whatever you are trying to do with it.

3 Comments

If you're pointing to a function using the classes pointer to function, why would the parentClass need to know where the variables are? Isn't that something the function itself is aware of being in a set memory location to begin with?
The member function itself is in a memory location, but it doesn't know which instance of the class it is a part of without being passed a pointer by the compiler. The member function is compiled and linked and then just one copy of it is sitting somewhere in memory. The program doesn't make a new copy of that code each time a new object is created--which means the same code gets called for ALL instances of that class, so the code doesn't know which instance is calling it unless it gets passed a pointer. The compiler passes it the pointer implicitly. But a simple function pointer won't.
Okay, that makes a lot more sense to me when explained that way. I guess the question should have been how to pass a pointer to a class function explicitly specifying which class instance without specifying the class type specifically..? I'm just confusing myself now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.