LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-27-2006, 12:27 PM   #1
lackluster
Member
 
Registered: Apr 2002
Location: D.C - USA
Distribution: slackware-current
Posts: 488

Rep: Reputation: 30
C++ Signals and Member Pointers


I know this has been hashed over many times, but I can't seem to find a suitable answer. I don't understand why this doesn't work:

Code:
#include <signal.h>
#include <iostream>

using namespace std;

class SigHandler {
  typedef void (SigHandler::*Func)(int);
  typedef void (*CStyleFunc)(int);

public:
  SigHandler() {
    Func func = &SigHandler::OnControlC;
    CStyleFunc cFunc = this->*func;

    signal(SIGINT, cFunc);
  }

  void OnControlC(int) {
    cout << "Control-C" << endl;
  }
};

int main(int, char**) {
  SigHandler sig;
  int i = 0;

  while (1) {
    cout i++ << ".)" << endl;

    sleep(5);
  }

  return 0;
}
I have an associated object (this) so why does g++ complain:

Quote:
main.cpp:13: error: invalid use of non-static member function
What does it care? I have an associated object and a pointer to a member function that is equivalant to void (*)(int). There must be a way to do this without globals/static member.
 
Old 03-27-2006, 01:28 PM   #2
ceros
Member
 
Registered: Oct 2005
Distribution: Kubuntu Edgy
Posts: 98

Rep: Reputation: 15
You try a different release of g++, maybe g++ 3.4.x or 3.3.x?
 
Old 03-27-2006, 01:35 PM   #3
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
maybe I missed something but what is this->*func? there is a local variable called func but I didn't see a member variable with that name.

Last edited by graemef; 03-27-2006 at 01:47 PM.
 
Old 03-27-2006, 01:46 PM   #4
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
I also think that line
Code:
Func func = &SigHandler::OnControlC;
should be
Code:
Func func = OnControlC;
and probably forget about cFunc.
 
Old 03-27-2006, 01:52 PM   #5
sm1else
Member
 
Registered: Oct 2004
Distribution: At home: Ubuntu, Debian Sarge
Posts: 56

Rep: Reputation: 15
Quote:
Originally Posted by lackluster
What does it care? I have an associated object and a pointer to a member function that is equivalant to void (*)(int). There must be a way to do this without globals/static member.
I should point out that this will probably not be all that accurate, I dont know how g++ implements things.

You dont really have a pointer to the object. This is because the object pointer is not stored in cFunc, only the function pointer is (you would need two void*'s to store both and cFunc is only one).
In fact func and cFunc are identical in this code.

I think its because at runtime the compiler will be unable to identify your object using only the function pointer. As a result it wont know where to lookup member variables for any purpose (reading or writing). Note that it doesnt matter if you use any member variables or not because there will be some implicit variables which the compiler will add since they are needed on the stack (the 'this' pointer would be a good example).
The static keyword prevents the use of non-static member variables within the function. This removes the need to know where the particular object is stored in memory and prevents some of the implicit variables such as the 'this' pointer.

The normal way around is to ensure the contents of the 'this' pointer is passed as an argument to the static function. You can then use the argument to access the original object. However this wont work in this situation.

If there will only ever be one instance of SigHandler then you can build SigHandler as a singleton class. The idea is to store a pointer to the object in a static member variable (equivalent to 'this'). Then when your signal handler is called, you make it obtain the pointer to the actual object and use that.

Hope that makes sense
 
Old 03-27-2006, 04:55 PM   #6
lackluster
Member
 
Registered: Apr 2002
Location: D.C - USA
Distribution: slackware-current
Posts: 488

Original Poster
Rep: Reputation: 30
sm1else, that's not a bad explanation. I thought that an address to a function should simply call that function and be done with it. Who cares if it's a member function or a function in another process? That's why I felt like I did have a pointer to the object. this is the object, pointing at the member function .. at this point I shouldn't need the object anymore - we're talking about a singular place in memory.

But what you're saying is that if I needed to access this->foo then it wouldn't know what the hell I was saying because wtf is this now, right? I guess without knowing the internals of exactly what happens when a class is compiled, this may be unsolvable for the desired method.
 
Old 03-28-2006, 07:03 AM   #7
sm1else
Member
 
Registered: Oct 2004
Distribution: At home: Ubuntu, Debian Sarge
Posts: 56

Rep: Reputation: 15
Thats right, it knows 'this' at the time of assignment, but when it uses the function pointer it doesnt know 'this'. It's all down to the fact that C++ isnt purely object oriented, its really C but extended with classes and objects.

Glad I could help

Last edited by sm1else; 03-28-2006 at 07:06 AM.
 
Old 03-29-2006, 12:41 PM   #8
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
This is one of those things where logic doesn't line up; you cannot bind a member function to an object in the way you can bind a data member to an object. Logic would say that since
Code:
//Data Member
int (Class::*) + Class* = int*
then this must also be true
Code:
//Member Function
void(Class::*)() + Class* = void(*)()
The reason you can bind a data member to an object is because there is actually a copy of that data member for each instance of the class; if a class contains an int, each object will have its own int, and all will have their own memory address, just like a global int will.

Member functions, however, only exist in a master table for the class; the actuall binary code for the function is not duplicated for each instance. For this reason, the function call needs a this pointer. In order to bind the two together, the program would have to turn the member function into a static function (by copying the binary code and doing some run-time recompilation), which is beyond the capability of pretty much any program.

What you need is a functor; this will allow you to bind a member function to an object and call it like a global function via an operator (). All you really need is a pointer to an object, a pointer to a member function, and an operator ().
ta0kira
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ - problem with pointers to class member functions Nylex Programming 3 01-15-2006 10:14 AM
!!! about signals !!! b2na Programming 4 02-04-2005 12:34 AM
Signals Speek Programming 2 12-24-2004 04:58 AM
LQ member progress status from member to senior member............. emailssent LQ Suggestions & Feedback 3 10-11-2004 01:31 PM
pointers to functions/member functions champ Programming 2 03-28-2003 06:22 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:47 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration