The main benefit of using abstract classes (interfaces) like this is that the application doesn't need to know the internals of the library at compilation or linker time. This allows the library to be dynamically loaded and instantiated as a plugin.
True. But AngelScript as a plugin? Does it even work as a plugin? I haven't ventured beyond the C++ binding API, so correct me if I'm wrong, but wouldn't the application require knowledge of AngelScript before hand to bind it? It wouldn't really be a plugin if the application needs it. It would just be a dynamically-loaded library.
The ANGELSCRIPT_VERSION argument to asCreateScriptEngine() goes along with that. By having the application provide the version of the library it has been compiled to use, AngelScript can validate this at runtime in order to avoid runtime crashes in case the application is expecting a different version of the library than is actually available.
I hadn't thought about that.
I understand that you have no interest in loading the script library dynamically so these benefits have absolutely no meaning for you, but AngelScript is not written for just a single application in mind. There plenty of other application developers that are thankful for the abstract classes, because without them they would have to implement the abstraction layer themselves;
I don't mean to come off as rude, but would you mind giving me an example of AngelScript saving the day with PImpl? The library seems virtually exclusive to game engines, which certainly don't dynamically load modules as important as the scripting libraries. I know the library's usages can extend beyond just games, but it makes it that much harder to understand a true scenario where PImpl is important. It just seems like a very weird scenario to plan for given how the library is typically used. Lua uses a form of PImpl (or whatever it's called in C), it's used well beyond just games, yet the only scenario I've heard about it benefiting (I say benefiting loosely, because re-compiling wouldn't be that much of a hassle) from it's PImpl-like interface was to simply update the library's DLL without re-compiling while maintaining the ABI.
You're right that dynamic (heap) memory has an overhead compared to local (stack) memory, but in practice, for the AngelScript object instances that you'll interact with this overhead is negligible. I cannot imagine any practical use of AngelScript where you would create a script engine instance locally for use only within that single function (not counting the main function, of course).
I don't mean to sound like this is some astronomical issue. I don't believe using pointers and a bit of dynamically-allocated memory makes much of a different either (it's a scripting language that's much slower than C++, tuning for best cache performance is a relatively minor issue). As I said, Lua uses it too, I only don't care because it's written in C so it saves me from typing &s everywhere (that and Lua goes crazy with dynamically allocated memory anyhow) . It's just something that I don't quite get given the syntax of C++ would allow for clean code and stack-allocated objects.
Also, just because it's stack-allocated doesn't mean it isn't practical to just throw it in the game loop function (or even just main, like you said, if the application is not a game) and just use references. My issue is where it's allocated, not how it's referenced.