• Advertisement
Sign in to follow this  

What does this mean? (syntax question)

This topic is 4591 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I found the following line in a C++ program and was puzzled by it.
HWND (*e)(embedWindowState *v);

I understand HWND *v is a pointer to an HWND but what's the meaning of the above code? Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Its a function pointer. You store a function in it and call it later.

HWND (*e)(embedWindowState *v);
e = someFunction;
e(someEmbedWindowState);

Share this post


Link to post
Share on other sites
To expand on what mike said:

#include <iostream>

double pie( int num ) {
return 3.14159265359 * num;
}

double answer( int /*unused*/ ) {
return 42;
}

double (*function)( int );

int main () {
function = & pie;
std::cout << function( 1 ) << std::endl; //prints out 3.1415...
function = & answer;
std::cout << function( 1 ) << std::endl; //prints out 42
}



The preceeding ampersand is not actually necessary in this context, but with member functions (which have their own special type of function pointer) it is. An example of that:

struct example {
double foo( int ) { std::cout << "foo" << endl; return 1.0; }
double bar( int ) { std::cout << "bar" << endl; return 2.0; }
double pie( int arg ) { return 3.14159265359 * arg; }
};

double (example::*function)( int );

int main () {
example my_example;
example * pointer_to_my_example = & my_example;

function = & example::foo; //ampersand is necessary this time

std::cout << (my_example.*function)( 10 ) << std::endl; //calls my_example.foo( 10 ) and prints the result
std::cout << (pointer_to_my_example->*function)( 10 ) << std::endl; //ditto, just showing the syntax used with pointers

function = & example::bar;
std::cout << (my_example.*function)( 10 ) << std::endl;
std::cout << (pointer_to_my_example->*function)( 10 ) << std::endl;

function = & example::pie;
std::cout << (my_example.*function)( 10 ) << std::endl;
std::cout << (pointer_to_my_example->*function)( 10 ) << std::endl;
}

Share this post


Link to post
Share on other sites
I just can't ever seem to get my head around those .* and ->* operators. I've very very seldom seen them used either.
From what I can gather, they're like calling functions through function pointers, but provide a way of calling a function which needs an implicit this pointer. Is that vaguely correct?
I still don't see myself ever using them though.

Share this post


Link to post
Share on other sites
In C++, a class's or struct's member function can be accessed through -> if you have a pointer to the class or struct, or . if you have an instance. Actual function pointers are used quite a bit less, although they are useful.

Edit: Corrected stuff, and I just now noticed you said the .* and ->* operators. My bad.

[Edited by - njpaul on July 31, 2005 2:02:40 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by njpaul
If you write classes you use the -> to access the member functions. If you use structures you use the . to access the data. Actual function pointers are used quite a bit less, although they are useful.


I might have misread what you said, but in C++ you use -> to access data/methods in a pointer to a class or structure and . to acces the data/methods of an instance to a class or structure:

class CMyClass
{
public:
int m_iAge;
int GetMyAge() const { return m_iAge; }
};

struct SMyStruct
{
int m_iAge;
int GetMyAge() const { return m_iAge; }
};

CMyClass* ptoMyClass = new CMyClass;
SMyStruct* ptoMyStruct = new CMyStruct;

ptoMyClass->m_iAge;
ptoMyClass->GetMyAge();
ptoMyStruct->m_iAge;
ptoMyStruct->GetMyAge();

CMyClass MyClass;
SMyStruct MyStruct;
MyClass.m_iAge;
MyClass.GetMyAge();
MyStruct.m_iAge;
MyStruct.GetMyAge();

Share this post


Link to post
Share on other sites
True, thanks for correcting me. I forget about the . with classes since I usually use pointers to them. -> is for pointers and . is for instances.

Share this post


Link to post
Share on other sites
Quote:
Original post by njpaul
True, thanks for correcting me. I forget about the . with classes since I usually use pointers to them. -> is for pointers and . is for instances.


. is also for references.

Share this post


Link to post
Share on other sites
Quote:
Original post by iMalc
I just can't ever seem to get my head around those .* and ->* operators. I've very very seldom seen them used either.
From what I can gather, they're like calling functions through function pointers, but provide a way of calling a function which needs an implicit this pointer. Is that vaguely correct?


Yes. When implementing ->*function for a custom pointer class, one must in fact return a full blown functor for equivilant functionality. Basically, if you have:

(A->*function)( B , C );

The statement (A->*function) would return a functor akin to this:

class call_function {
example * this_argument;
public:
... operator() ( b_type B , c_type C ) const {
return this_argument->function( B , C );
}
};


The design of overloading operator->* is however a bit brittle. The one class I've implemented this functionality had no less than 6 versions of operator->... const and non-const versions to handle each of these cases:

variable = my_smart_pointer->*member_variable; //->* returns reference to variable
(my_smart_pointer->*no_argument_function)(); //->* returns functor with "this_argument"
(my_smart_pointer->*single_argument_function)( 3 ); //->* returns different functor with "this_argument"

Of course this didn't handle: (my_smart_pointer->*function)( A1 , A2 , .. , An );

For N >= 2. For each extra argument to be supported one must implement two more operator->*s (const and non-const) plus any supporting functors.

Share this post


Link to post
Share on other sites
Cool, much appreciated thankyou[smile], that's certainly raised my understanding somewhat.
I know we have some code at work that uses those operators, so no doubt I'll have to maintain that one day.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement