Most times when an object shows up for work, it’s capable of performing as required, because its capabilities are advertised explicitly in its interface. However, life is not always that straightforward. This chapter will help you learn what to do when capabilities aren’t readily apparent.
This is pretty basic stuff here, really. I was hoping it’d be some amazing new insight into C++ that I had never seen before, but this is just a silly name for dynamic_cast. Even more silly is the final paragraph in the article:
“Capability queries are occasionally required, but they tend to be overused. They are often an indicator of bad design, and it’s best to avoid making runtime queries about an object’s capabilities unless no other reasonable approach is available.”
So the whole article seems to be about this amazing feature called a “capability query,” except in the end, you shouldn’t use it. Huh. 🙂
“Capability query” is a very misleading name. I’ve never heard polymorphism referred to as such before. Based on the title I was expecting to see some kind of discussion about reflection in C++ or something like that. Oh well.
I add myself in the line after BigZaphod and also wonder why this naming, I never heard to be called such before. Oh my, whatever, the new generation who will read&learn from this book will become geekier for using unheard terms ? Whatever.
On the other hand, on monday mornings (yup, today) I also show up as an object to work, but not always performing as required while still, my capabilities are advertised although not always explicitly in my interface “However, life is not always that straightforward” so you need to “learn what to do when capabilities aren’t readily apparent” if you want something from me in such mornings :]
Whatever
Are there any good (and fairly standard) approaches to reflection in C++?
I’m guessing there isn’t since it would require horrible pointer/offset stuff at runtime, and I’ve yet to see anything like it.
The natural and rather simple use of reflection seems to be the something that’s only available in languages with a virtual machine/runtime environment. Are JIT/HotSpot/etc capable of optimising reflection within native object code?
Do languages like Python etc use reflection when compiled to native code or do they use stubs or interfaces or some such?
When I started using reflection (in Java at the time) I was rather perplexed as to what the point was. Up until then I’d over-defined everything to avoid casting at all costs. Now I wish every language had these capabilities.
Do languages like Python etc use reflection when compiled to native code or do they use stubs or interfaces or some such?
Structural reflection could be informally defined as the ability to add, remove or modify attributes or methods of a class or object dynamically at runtime. This is usually offered in dynamic languages, such as Python. These languages allow the programmer to use reflection in order to improve flexibility of his code, performing certain tasks that will be very difficult to implement in statically type-checked languages such as C++ or Java. Java and C# have included introspection in their computational model: the first level of reflection that permits the programmer to inspect program’s structure at runtime.
tobaccofarm
Are there any good (and fairly standard) approaches to reflection in C++?
What’s your definition of “good” and “standard”? 🙂
If you’re willing to jump off the deep end, there’s C++/CLI:
http://www.ecma-international.org/news/ecma-TG5-PR.htm
http://msdn.microsoft.com/visualc/homepageheadlines/ecma/default.as…
It’s “good” in that it permits all the reflection capability os .NET. It’s “standard” in that it will become an ECMA standard.
On the downside it limits you to Microsoft platforms (Mono doesn’t have a C++/CLI compiler, and has no plans for one).
Alternatively, do you need runtime reflection capabilities? If you can make your decisions at compile time, you can always use a traits-based framework. This is more of a “capability query” in that you can determine whether something is permitted before attempting to do it. For example, for std::reverse() you can choose, at compile time, whether to use a pointer for iteration or a class iterator; see the example here:
http://www.sgi.com/tech/stl/iterator_category.html
This approach is “good” in that it works, and “standard” in that it should work everywhere, but it limits you to making decisions at compile-time, which may be undesirable.
If you want full reflection capabilities such as Java, C#, Python, and other languages support, you’re more limited. The C++ language doesn’t readily support Reflection, as it’s a contrary goal (do as much at compile time as possible; runtime selection is limited to virtual functions and typeid — this is deliberate). This doesn’t mean that there are no solutions, rather it means that such solutions are custom, not necessarily general, and may require additional effort.
Liked: short, sweet, pointed discussion of broad topic range. Even for the experienced guru, a cliff-notish collection of thoughts like this is most handy. The neophyte benefits by a non-overwhelming introduction to topics.
Disliked: glaring omission of http://boost.org. Ton of germane work overlooked. Boo hoo.
I was about to answer much the same way you did but will instead defer to you since you said it so well.
I’m confused, however, by the statement, “This approach is “good” in that it works, and “standard” in that it should work everywhere, but it limits you to making decisions at compile-time, which may be undesirable. “ In what sort of situations would compile-time decision making become undesirable? I’ve personally never run into this situation but have instead encountered the opposite with runtime reflection being what’s undesirable.
For example, I’ve found on more than one occasion where someone will try to choose an algorytm based on class name. What happens usually is someone will then switch on class name in order to branch appropriately. This is, obviously, very undesirable as the switch code will have to be modified every time someone decides to add a new class to the system, reducing maintainability.
If I use compile-time switching, OTH, I can simply provide my new class and a specialization for algorytm I wish to switch on. This is much cleaner and easier to maintain than before.
Thoughts?
As noted before, dynamic_cast really isn’t “capability queries” that much… My initial thought was something COM-like (the use of QueryInterface to figure out at run-time whether some instance supports an interface). That has platform-dependency hits though (does anyone know of similiar systems, beyond Microsoft COM and Mozilla’s XPCOM?)