|
-
February 14th, 2005, 03:35 PM
#1
Problem using a method pointer
Consider the following class:
class Alpha
{
public:
virtual bool Print2(void);
virtual bool Print1(void);
Alpha();
virtual ~Alpha();
bool ( Alpha::*Print)(void);
};
bool Alpha::Print1()
{
printf("Alpha 1\n");
return true;
}
bool Alpha::Print2()
{
printf("Alpha 2\n");
return false;
}
Now the following test code:
Alpha Test1;
Test1.Print = Alpha::Print1;
Test1.Print();
Test1.*Print();
(*Test1.Print)();
None of the above syntax is correct for calling the print method. How do I call it?
-
February 14th, 2005, 03:53 PM
#2
Re: Problem using a method pointer
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
February 14th, 2005, 09:16 PM
#3
Re: Problem using a method pointer
hi all,
see the following:
static void getParam();
typedef VOID (*funcPtr)( void );
typedef struct {
funcPtr openfunc;
int iPrt;
char sPrtname[20];
} FuncDetail;
static void getParam()
{
//
}
class A
{
void setFunc()
{
FuncDetail fd;
fd.openfunc = ::getParam; //ERROR
}
}
my problem is it compiled well in borland c++ 6 and but at running it give the access violation.
pls can anyone tell me that whats wrong in my code?
thanks in advance.
-
February 15th, 2005, 01:07 AM
#4
Re: Problem using a method pointer
 Originally Posted by Graham
(Test1.*Print)();
Didn't work... I got a term does not evaluate to a function error in VC++
 Originally Posted by thilag
Code:
static void getParam();
typedef VOID (*funcPtr)( void );
typedef struct {
funcPtr openfunc;
int iPrt;
char sPrtname[20];
} FuncDetail;
Are you missing something? the code makes no sense to me...
The syntax for typedef is:
Code:
typedef existing_type new_name;
e.g. typedef unsigned int uint;
How come your code compiled with that typedef statement ???!!
Also, there's no semicolon after class definition...
I had to make the following changes to make your code compile, without any runtime errors:
Code:
typedef struct {
void (*funcPtr)( void);// openfunc;
int iPrt;
char sPrtname[20];
}FuncDetail;
static void getParam()
{
//
}
class A
{
void setFunc()
{
FuncDetail fd;
fd.funcPtr = ::getParam; // NO ERROR
}
};
void main(){
A a;
}
-
February 15th, 2005, 07:14 AM
#5
Re: Problem using a method pointer
hi,
my code is working fine in borland in some other places of my application (application is 2 1/2 crore line lengthy). truely i am doing internationalization for this application. so i cant change the format. but when i try to assign function for this function pointer it gives runtime error(access violation).
missing of semicolon is my mistake. pls forgive me.
anyway thanks a lot. if u have any other way pls give me.
-
February 15th, 2005, 07:37 AM
#6
Re: Problem using a method pointer
Sorry, I should have said
(Test1.*Test1.Print)();
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
February 15th, 2005, 11:32 AM
#7
Re: Problem using a method pointer
Ok Graham I cut and paste your statement, and it worked.
Only when I look at it, it makes no sense to me. Can you explain to me why it works and what it really looks like to the compiler?
To me it looks like you are calling Method Test1 from Class Alpha. Of course Test1 doesn't exist as member of Alpha, so it wouldn't seem like it should work, but it does.
-
February 15th, 2005, 11:42 AM
#8
Re: Problem using a method pointer
 Originally Posted by BigEvil
Are you missing something? the code makes no sense to me...
The syntax for typedef is:
Code:
typedef existing_type new_name;
e.g. typedef unsigned int uint;
How come your code compiled with that typedef statement ???!!
This is perfectly legal.
Code:
typedef VOID (*funcPtr)( void );
This is how you typedef a function pointer, so that you do not have to keep repeating the declaration. It also helps when you want to do things like:
Code:
typedef void (*MyFunc)(void);
typedef std::vector<MyFunc> MyFuncVector;
Viggy
-
February 15th, 2005, 11:47 AM
#9
Re: Problem using a method pointer
It means that first you take the address of method, which is the field of Test1 object, by expression (Test1.Print), and then call this function as a method of object Test1 (accidently the same object) by expression (Test1.*Test1.Print)(); The same question was arisen here not long ago, here is some code as an example:
Code:
#include <stdio.h>
class test
{
public:
typedef void (test::*func)(int);
func fptr;
char* name;
void func1(int a){printf("%s::func1(%d)\n",name,a);}
void func2(int a){printf("%s::func2(%d)\n",name,a);}
test(char *name){fptr = &test::func1; this->name=name;}
void callit(int arg)
{
(this->*fptr)(arg);
}
};
int main()
{
test test1("test1"),test2("test2");
test1.fptr=&test::func1;
test2.fptr=&test::func2;
test1.callit(1);
test2.callit(2);
(test1.*test1.fptr)(3);
(test1.*test2.fptr)(4);
(test2.*test1.fptr)(5);
(test2.*test2.fptr)(6);
(test1.*&test::func1)(7);
(test1.*&test::func2)(8);
return 0;
}
Output:
Code:
test1::func1(1)
test2::func2(2)
test1::func1(3)
test1::func2(4)
test2::func1(5)
test2::func2(6)
test1::func1(7)
test1::func2(8)
Last edited by RoboTact; February 15th, 2005 at 11:50 AM.
"Programs must be written for people to read, and only incidentally for machines to execute."
-
February 15th, 2005, 11:47 AM
#10
Re: Problem using a method pointer
 Originally Posted by DeepT
Ok Graham I cut and paste your statement, and it worked.
Only when I look at it, it makes no sense to me. Can you explain to me why it works and what it really looks like to the compiler?
To me it looks like you are calling Method Test1 from Class Alpha. Of course Test1 doesn't exist as member of Alpha, so it wouldn't seem like it should work, but it does.
If you work it out, it says: "call whatever is in 'Test1.Print' on object 'Test1'". Think about class functions:
Code:
class MyClass
{
public:
void SomeFunc();
};
int main()
{
MyClass obj1;
obj1.SomeFunc();
}
This says, "call the function 'SomeFunc' on 'obj1'". In your case, you have a function pointer stored in the variable 'Print', right? Forget classes for a second, to call that function you would use the syntax:
However, this is a member function that is stored in Print. So, you need to tell the compiler what object to call the function on. Therefore, you get:
Code:
(Test1.*Test1.Print)();
Viggy
Last edited by MrViggy; February 15th, 2005 at 01:27 PM.
Reason: Fixed typo...
-
February 15th, 2005, 01:02 PM
#11
Re: Problem using a method pointer
Well, that's saved me answering... .
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
February 15th, 2005, 01:29 PM
#12
Re: Problem using a method pointer
Yeah, you caught me on a good day! Well, that and it takes about 4 hours for my testsuite to run, and of course, it crashed last night, so...

Viggy
-
February 15th, 2005, 02:24 PM
#13
Re: Problem using a method pointer
Ok.. Well it makes a little more sense, but maybe I do not understand how compilers work.
This is how I thought they worked:
FUNCT *FunctPtr;
FunctPtr = MyClass::DoSomething;
Now at this point I thought FunctPtr contained an actual address of a function. So in terms of machine code the paramters are pushed onto the stack, and the program counter jumps to address of FunctPtr.
In this context I do not understand the (Test1.Test1.*Print)() syntax.
However, if FunctPtr was really an index into a VMT and not a real address, then Test1.*Print would resolve to some index value such as 5, and then Test1.(Index)() means excute whatever the 5th function is in your class. If this is how it works, then I understand it a bit better.
Is this how it is working?
-
February 15th, 2005, 03:17 PM
#14
Re: Problem using a method pointer
Are you missing the difference between a pointer-to-ordinary-function and pointer-to-member-function? They are two entirely different things and are not interchangeable.
Non-static member functions implicitly have an extra parameter of type pointer-to-class. This (hidden) parameter is used to initialise the this pointer inside the function. Think of it this way:
Code:
void foo::function(); // would translate to:
void function(foo* this); // if it wasn't a class member
// incidentally...
void foo::function() const; // becomes
void function(const foo* this);
Now, because of this hidden extra parameter, pointers-to-member-functions have to have an object to be called on - the object will be used as the this parameter. To do that, we use the special syntax: (object.*funcptr)(); where object will be used to initialise the this parameter for the member function pointed to by funcptr. The translation to a non-member pointer is (*funcptr)(&object);
So, if we have:
Code:
class Alpha
{
public:
virtual bool Print2(void);
virtual bool Print1(void);
Alpha();
virtual ~Alpha();
bool (Alpha::*Print)(void);
};
int main()
{
Alpha Test1;
Test1.Print = Alpha::Print1;
(Test1.*Test1.Print)();
}
So, Test1 (before the .*) is object and Test1.Print is funcptr. You seem to have confused yourself by making the function pointer a member of the class that it points to a member of, so you need to reference the object twice. Do the translation: (*Test1.Print)(&Test1);
So, when you're dealing with pointers to member functions, remember that you need two things: the pointer and an object to call it on. When in doubt, remember the form (*funcptr)(&object); and put object to the left of the .* and funcptr to the right.
Incidentally, if you have a pointer to an object (rather than the object itself), then you can use the syntax (pointer->*funcptr)(); (and ignore the "address-of" operator in the (*funcptr)(pointer) form). (If Test1 was a pointer in your example, the call would have been (Test1->*Test1->Print)(); )
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
February 15th, 2005, 03:43 PM
#15
Re: Problem using a method pointer
Heh, this time Graham caught me at lunch!

Viggy
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|