On Properties in C Plus Plus
From StoneHome
For a long time I've been pretty torn on the issue of properties in C++. On the one hand, in Delphi where I first learned them, they're hella convenient. They allow for a sort of conceptual abstraction between functions and variables that a lot of people are very bothered by at first (among whom I can count myself.) "Getters and setters are jus' fine." Etc.
I'm going to go out on a limb to justify why properties are good conceptually, first. Then I'll get into their practical implementation and implementation issues. Finally, I'm gonna do some complaining like usual.
Thing is, we're often admonished that objects aren't classes, that they're UDTs. If one chooses to adhere to the viewpoint of making classes to represent types - which C++ has done wholeheartedly through syntactic sugar like operator overloading - then one has already ceded that functional definition should be allowed to step in when concrete behavior is expected.
UDTs have their operators overloaded not only for convenience. The algorithms in the STL could have worked just as easily with .lessThan() instead of ::< . Thing is, that could have worked just as well in C, and it took a long time after other languages exhibited UDTs before someone wrote C With Classes. There's a certain importance to treating your types in the same way that you treat machine types; it allows one to accept that there's no practical difference between int and CInteger at the conceptual level.
Another less obvious fundamental shift occurred in C99, with the introduction of the Complex type. Things held as simple types conceptually, such as mathematical primitives, are beginning to be allowed to have members. This isn't as disconnected an issue as it first sounds. When one wants to implement a UDT to simulate a primitive - say, an integer larger than the host platform's native limits, or an arbitrary precision real - then it's important to be able to work with the faux primitive as you're used to, rather than writing C reminiscent of LISP, which is distracting in a C context and difficult for people not used to both paradigms.
If complex may have POD members, then when we implement arbitrary-precision float complex, we're going to want to be able to present the data members from functions. Conceptually, properties are the conceptual analogue of data members that operator overloading is to expressions. Many creation-oriented patterns and idioms make the same analogue for allocation owing to more complex functional behavior, such as abstract factories, flyweights, pooling and re-use mechanisms, and compositors. It is arguable that this is the general behavior of containers, though in C++ a more powerful mechanism for containers (templates) has since supplanted them; however, some old codgers may remember the days of generic stacks and vectors and so forth passing void pointers willy-nilly (in this respect, MFC is an archaeological treasure trove.)
I'll try to keep my discussion of OOP short. I believe that properties fundamentally support encapsulation. A simple but potent example is adapting to changing requirements.
Another more complex example is that of the data driven machine.
'Course, this is a dangerous one. Much like threads threw state-safe data access into the spotlight and classes threw mutability and const correctness into the spotlight, a data driven machine with dynamic data is going to show off some very nasty problems with volatility correctness, and legacy stuff may occasionally choke due to volatility errors and caching assumptions which at first aren't well understood, but hey, that's
