|
Why not?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thats what this thread is all about.
If you want to call a funciton pointer in a class for another member of that class you cant just call (*pProc)(), you need to prefix it thus: (this->*pProc)(). ( or (*this.*pProc)(), whci is cleaner, though VS hates it).
==============================
Nothing to say.
|
|
|
|
|
Well, if you remove this then the syntax would be exactly (or, at least compatible with) the one used for bare C functions. That would be a bit ambiguous.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
If you remove the this-> it doesnt compile.
==============================
Nothing to say.
|
|
|
|
|
That's my point. It shouldn't compile (it would be ambiguous).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Fat__Eric wrote:
You dont need to specify 'this->' when calling member funcs, you just call them by name. Thats the point I am making.
right. and the point i'm making is that the C++ designers made the 'this->' implicit when calling a member function directly from inside the class: the compiler simply assumes a call to non-static member fn CFoo::Whatever() from inside a class is the same as a call to this->Whatever() - they just let you omit the 'this->' for such a common case. but the C++ authors didn't provide for that little bit of syntactic shortcut when dealing with member fn ptrs. maybe there's a subtle technical reason they didn't give the same shortcut for member fn ptrs, but i haven't been able to find it. it seems obvious that if you can assume 'this' for a normal member fn call, you can assume this for a member fn ptr call.
Fat__Eric wrote: Used a lot in C though. A heck of a lot. Surprises me they werent better catered for in C++.
but not so much in C++. i can count the number of times i've used them in C++ on one finger - and that was when doing a quick-n-dirty conversion of an old C program to C++.
|
|
|
|
|
The reason was it was ambiguous.
They could have provided a different dereferencing operator for member function pointers, something like ::* maybe, but alas they didn't.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
ahmed zahmed wrote: The reason was it was ambiguous.
no, it isn't. or, it wouldn't be. (it is now, since the C++ rules don't allow for this kind of thing, but that's not my point)
the compiler already knows how to do the implicit 'this' with member functions. it could do the same thing with member fn ptrs. assume unqualified member references are to 'this'. if a member function pointer for the class is used inside a non-static member function? assume 'this'.
|
|
|
|
|
yes, it could do that, but then calling a c-style function pointer would need a new syntax then.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
why? one syntax works for function calls now:
strcpy(foo, bar);
memberFnOfThisClass(foo, bar);
staticMemberFnOfThisClass(foo, bar);
std::sort(blah1, blah2);
|
|
|
|
|
When you use a pointer data member the syntax is *pVar = 10; or some such. No need to write
this->*pVar = 10;
So why not with member func pointers?
In fact func pointers are very useful, once you get to have used them a fair bit, they are indispensible, I just never realised how crappy the syntax for them is in C++.
==============================
Nothing to say.
|
|
|
|
|
Fat__Eric wrote: So I use a lot of function pointers in C
You don't however use member function pointers in C. Because they do not exist.
That said you shouldn't be using a "lot" of function pointers in C++ because there are probably better ways to do what you want in C++ without using them.
Perhaps what you want is a static member function pointer.
Or even just a function pointer - which would be exactly like it is in C.
|
|
|
|
|
jschell wrote: they do not exist True, unless you think of function pointers in a struct as member functions. Then the dereferencing syntax is very similar.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
You know, if they are going to put the feature in the language, then saying "you shouldnt use that feature because there are better ways of doing it" is total bollocks.
The fact is the feature exists, yet the syntax is inconsistent with non pointer functions.
OK, take pointer member variables. Do you have to reference them as 'this->*pInt = 1;'
No, you just write '*pInt = 1;' in any function belonging to that class.
Yet you cant for a function pointer. You cant do (*pProc)(blah blah blah) you have to do (this->*pProc)(blah blah blah).
It is wrong!
==============================
Nothing to say.
|
|
|
|
|
Fat__Eric wrote: Yet you cant for a function pointer. You cant do (*pProc)(blah blah blah) you
have to do (this->*pProc)(blah blah blah).
I don't see that.
At best you are suggesting a shortcut that would apply to limited situations. It would require all of the following.
1. One needs a member function pointer to method X in class A.
2. Class A needs a variable of that type.
3. Class A needs to use tht variable to call itself.
I have very rarely seen a need for 1. Perhaps less that 10 times.
I have never seen a case for 2.
If I saw 3 I would suspect that there is a design flaw. I wouldn't be surprised if 2 represented a design flaw as well.
If there is any valid case for 3 then the there are so few situations that complicating the syntax just to provide a shortcut isn't worth it.
|
|
|
|
|
jschell wrote: At best you are suggesting a shortcut that would apply to limited situations
As stated, when you use a pointer data member you use *pInt = 10; or some such. You do not need to use this->*pInt = 10;
So IMO it should be the same with pointer function members.
==============================
Nothing to say.
|
|
|
|
|
Fat__Eric wrote: As stated, when you use a pointer data member you use *pInt = 10; or some such. You do not need to use this->*pInt = 10;
Which actually would seem to clarify exactly why your proposition is not reasonable.
The scope of the your example is the referenced int. Whether it is in the current class or another class or even global the scope is still the referenced int. One single scope. No other scope is possible.
A member function pointer belongs to a single class instances. Thus there can be zero, one or many (hundreds) of scopes.
The scope must be specified when the member function pointer is called. There is no other possibility.
|
|
|
|
|
If you think of a class as a struct with function pointers, then the syntax makes sense. It would actually be similar syntax in straight C:
That is if I have:
typedef ULONG (*SomeFuncPtr)(PULONG, PVOID)
struct foo
{
SomeFuncPtr func;
};
Then code in some other function:
ULONG SomeFunc(PULONG pVal, foo* bar, PVOID pOpt)
{
...
(*bar->func)(&x, NULL);
...
}
the * is just moved is all...
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Yes, it is easier with an instance of the object used externally to the object. My gripe was when used internally; why calling a func pointer specifically typedefed as belonging to the class should require an explicit this-> but calling a func doesnt.
Its almost racist. (Well, pointerist perhaps)
==============================
Nothing to say.
|
|
|
|
|
see my replies to Chris Loslinger above.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
The problem is that operator*(MyFunc) is ambiguous, whereas operator->*(MyFunc) is not. You may have missed the point that this->*pProc is not equivalent to this->(*pProc) or (*this).(*pProc) . neither of the latter versions would compile, because they are just as ambigous as (*pProc) !
A member function pointer isn't simply an address, it is a small struct that contains various bits of information that are needed to determine the actual function address, depending on whether the function is static, inline, virtual, or ordinary, whether the function type was defined in a base class or not, and maybe other factors as well. The compiler therefore wouldn't be able to tell if by invoking operator* you want to access these struct members, or rather call a function whose address is encoded by that struct!
At least that is my (incomplete) understanding of the matter. I may not be entirely correct, but you're free to google for more details. I've found 'Pointers to member functions' a very insightful article on the matter, although I couldn't pinpoint a concise answer to your question in there.
P.S.: I've just thought to search for this topic on CP and found this article. Just like the above link it explains a lot about member function pointers and their (lack of) use, but you might not like the article as much because it makes a point of how utterly useless member function pointers really are, except for the one thing this article is about: fast delegates.
modified on Wednesday, September 14, 2011 5:25 AM
|
|
|
|
|
Thanks, thats the first good answer.
==============================
Nothing to say.
|
|
|
|
|
Hi,
I'm running into a problem that I've been puzzled for 2 days already. If anyone has any suggestion on how to trace it, I truly appreciated.
I have a MDI application with multiple tabs in MyView. I also have a panel which list files and folders from My Computer.
I can drag a file from the panel onto any tabs in MyView and it would accept the drop. However, if I drag a file from my desktop or anywhere outside of my application, the + sign shows up like it's trying to accept drop, but when I drop the file, OnDropFiles event doesn't get triggered at all.
I've check that I have ON_WM_DROPFILES()in BEGIN_MESSAGE_MAP, DragAcceptFiles() in the OnInitialUpdate, afx_msg void OnDropFiles(HDROP hDropInfo) in the header file.
Switching to OleDragDrop also behaves the same way...If I didn't setup properly, it wouldn't even work when I drag the file from the panel, right? I'm really running out of ideas on how to tackle this one.
Any ideas would be tremendous help to me~~
Thanks,
Helen
|
|
|
|
|
If i may suggest, instead of relying on wM_DROPFILES and DragAcceptFiles, rather use DoDragDrop[^], RegisterDragDrop[^] / RevokeDragDrop[^]. As i know, WM_DROPFILES is the "old" method of doing this.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
modified on Monday, September 12, 2011 4:37 AM
|
|
|
|
|
Thanks for your reply~~ I'll give it a shot. Do you know what might have caused the drop event to only get triggered from the same application but not from outside the application?
|
|
|
|