Please make JuceApplication::invoke() virtual

After wondering for an hour or so why my application does not receive any “scripted” commands, I found that invoke() is non-virtual. I had to type cast each message receiver to the most specific subclass to make it work. This was a bit tricky, because at the places where these commands are sent, the app class is not known.

It would make sense to make invoke() et al virtual, so we can write generic scripting for applications.

(off topic rant:)

On a side node, the more I get into complex development, the more I am having a hard time getting along with the limitations of C++. Man, is this frustrating and depressing. Isn’t there the slightest possibility to use a clean polymorphism? I can’t seem to get used to the absurd fact I have to type cast message receivers in order to ensure that the right code at the correct level in the class hierarchy is executed (shudder). How is a sender supposed to always know all subclasses in advance? In order to implement algorithms in a base class (“behavior”), I need to make sure they can be overridden or extended by derived classes as needed later on. This is what I learned is inheritance and polymorphism.

I am inclined to radically just making everything virtual.


It’d be crazy to try to override invoke(), that’s absolutely not what it’s designed for. It’s perform() that you’re supposed to override.

Sounds like you’ve completely misunderstood the whole thing - your rant makes no sense at all! Take a few deep breaths, and go and read some c++ inheritance tutorials.

Thanks, that makes a difference. I was looking at the wrong methods.

Obviously, as there are so many others who are quite happy with it. Sorry for the noise.

I must admit that I am spoiled by 25 years of object orientation. I grew up in a world where nil is the sole instance of UndefinedObject, true is an instance of True, which inherits from Boolean, and Class is a subclass of Behavior. There is nothing else than sending messages to objects, no keywords, no special syntax. It’s easy to handle 10,000 and more classes in a single browser and live systems can be refactored while they are running. Coming from such a dynamic background, the static inheritance of C++ with all its do’s and don’ts is really hard to get used to. So please bear with me. I promise I’ll become a brave soldier :wink:

A very simple example that explains the limitations I am struggling with: MyApp::getInstance() does not give me a pointer to MyApp. It gives me a pointer to JuceApplication, which is pretty useless in most cases. If I do something like

it complains that JuceApplication does not understand doSomething(). In order to get around this, I have to type cast:

which, at least IMHO, looks noisy and messy. If there was real polymorphism and inheritance, JuceApplication could implement getInstance() in a way that returns a type of whatever class this message was sent to. Or simpler put: this would resolve to the class the code is currently executed in, not the class it was initially compiled for.

a) You’re mis-using your terms: this has nothing to do with polymorphism or inheritance, it’s static vs dynamic typing.
b) Why are you putting significant functionality into your JUCEApplication class? That’s bad design - it should just be a launchpad for other classes, and should do very little itself.
c) If you have some code that needs a pointer to your app object, then give it a pointer to that object!! Don’t make it call static methods to try to find some global pointer, that’s terrible encapsulation, in any language!
d) Even if you did have a good reason to constantly get this static pointer and dynamic_cast it, you could wrap it in a trivial one-line method, e.g. static MyApp* MyApp::getInstance() { return dynamic_cast<MyApp*> (JUCEApplication::getInstance()); }, and call that instead! D.R.Y!

It just sounds to me like you’ve got some sloppy habits that you managed to get away with in dynamically-typed languages - hopefully a bit of C++ boot-camp will kick some discipline into you! :wink:

I don’t. It just a main hook for command scripting that I need.

Oh, I rarely do that. The above code was meant to be an example.

I could wrap a lot of things into nice one-liners. I could even write a lot more macros and templates to get me the fuzzy warm feeling of dynamicallyness, but that’s not the point. The point is that less redundant code is better.

Sure do I know that. But inheritance and polymorphism require dynamic typing to a large extent in order to work as intended. Virtual methods are an attempt at dealing with this. However, polymorphism is much more than operator overloading or method overriding. Polymorph behavior is impossible with C++, which is why there are templates.

Yeah! It already did so far. Except for the occasional confusion here and there, I seem to move forward quite fine. Thanks to your great work. :smiley: