I think I wasn’t clear enough. I think you are both right, a pointer make handling much more simple.
If you read my previous posts, I was saying that the string solution make the code easier to write (less code to write), and is still easy to read. However, this implies searching which is a pain, and limit the possible action you can do without a lot of code.
The pointer solution is less easier to write (as you should check the pointer first, then cast it to the right type), but is easier to deal with. Pointer doesn’t prevent you from searching, as long as you have different component types (which is the case 99 out of 100 times), because if you just cast the pointer to a button while it is a text editor, it is going to crash as soon as you use it (or you will have to check if the cast worked, and then, it is exactly like the string approach).
Ok, searching is a lot faster because it is using integer instead of strings (of course, if you use a dynamic_cast then, the compiler generate RTTI code to check the conversion and then you directly loose the gain you expected).
The solution I am advertising is using an ID so you will still be able to keep the code readable and easy to write (with a correct enum), it is possible to check for ID ranges (so this solves the different component type issue, if you want to apply the same code to all your button, simple put a if (ID >= firstButtonID && ID <= lastButtonID).
With a switch, the search could be O(1) (instead of O(n)).
Then, I agree that no solution is better than another. If your handler has no possible knowledge of the component, like “addAndMakeVisible(new textButton(…)) in the constructor”, then the pointer is the only solution that would work. At the same time, it is not with “no cost” like you are saying, because you have to cast it (which could lead to RTTI code if you use dynamic_cast or crash if you don’t), you have to take care of the usual pointer issues (if I delete it, it is going to crash when leaving the method), add documentation for the pointer issues in order to avoid them, all of these being a pain when maintaining such code.
A good solution, like I said earlier, would be to have both system (default handler with string (or better, ID), only called if you don’t override the non default handler with pointers).
Even better, the component could use a template argument for switching from both cases at compile time at no cost.
Angrycat, I don’t understand your example. Could you show me a simple code so I could see what you mean ?