- Community Pick
- Experts Exchange Approved
Properties are a first-class language element of C#, Visual Basic, Delphi, Python and other languages. Over the years, proposals have been submitted to C++ standards committee to add the feature to our favorite programming language, but it's never quite made it into an official standard.
Why Properties?
What's the point? Why use properties?
The main idea is based on something that programmers have been struggling with probably ever since Lady Lovelace wrote the first computer algorithm -- data encapsulation. You want to manage and limit direct access to data elements so that only those parts of the program that need it can get to it. But the usefulness of properties goes well beyond that. Here are some things you can do with properties and some examples:
- Data encapsulation, data hiding. Prevent direct manipulation of data elements. Avoid programming errors related to changing a data value incorrectly or at the wrong time.
Example: Protecting list integrity in a multi-threaded program; e.g., transparently apply a lock or a critical section around code that manipulates the list.
- Data validation; data value enforcement. It's a way for you to make your object self-correcting.
Examples: Forcibly "pin" a data value so that it is guaranteed to be within a certain range of valid values. For instance, ensuring that a "percentage" variable will be between 0 and 100, inclusive. Make sure that a ZIP Code is exactly five or nine digits.
- Transparent data manipulation. The data itself might be stored in a form that is inconvenient for other parts of the program to use. The property logic does a conversion transparently.
Examples: Encrypt a password, Social Security Number, or other sensitive data when stored but have the clear-text value at hand when used in the program. Provide normalized handling for database NULL values. Transparently "escape" and "unescape" text that is to be displayed in an HTML page or used in an SQL query.
- Data source transparency. The programmer (and the rest of the system) does not need to know exactly how or from where the data was obtained. He just needs the value.
Example: The value is obtained through a COM-object method that might, in turn, access a database hosted on a remote system. But it looks like a local memory variable in the program code.
- Invoke a function call to get or set the data by using simple assignment semantics. Hide the "dirty" low-level implementation. This is possibly the most commonly-cited value of properties.
Examples: Instead of calling MoveWindow(...), you can just set oWin.rPos=r; Instead of calling ShowWindow(h,SW_HIDE) just set oWin.fIsVisible=false; Rather than calling SetPixel(x,y,rgbColor) just use Canvas[y][x]=rgbColor; Instead of calling GetPrivateProfileString() for a user-settings option value, just use sUser=oSettings.sUserName;
Accessors: getters and putters
If you recognized any of the above scenarios (that is, if you have done much C++ coding), you have probably written your share of getXxxx() and putXxxx() member functions in your class objects. And you have run into the problem: Using accessor methods can be syntactically awkward:
...instead of simply:
In short, that's what this is all about: Anything that you can do with a property can be done with a pair of get/put member functions, but the programming is not as convenient. Why should VB and C# programmers have all of that heavenly convenience while we poor C++ programmers are damned to spend eternity in a get-and-put purgatory?
Well, we are not. First, several popular C++ compilers provide non-standard support for properties. But even lacking direct support, the C++ language boasts the ability to write operator overrides... and that means that it is possible to implement property semantics.
C++ Property Implementations
Several compilers provide non-standard extensions, and there are a number of ways to attack the problem using templates and/or macros. Let's look at the options.
Non-Standard Extensions
For many of us, the first and most obvious place to look is in our compiler's documentation. If it provides a non-standard extension with support for properties, then unless you intend to port the code to a different compiler, why not use it?
Microsoft's Visual C++ has supported such a non-standard extension since (at least) the 2003 release. It works perfectly and is easy to use. You just add...
__declspec( property( get=YourGetFn, put=YourPutFn ) ) int yourPropVarName;
... in your class declaration. Code up the YourGetFn and YourPutFn and add the private variable that they will access, and you are done.
That works whether you are programming native or using CLI (incidentally, the ECMA C++/CLI standard elevates property to first class status and you don't need to use the somewhat awkward _declspec syntax in the declaration when doing .NET progamming).
Note that the semantics are perfect -- property variables work transparently to the code that uses them. For instance, you can use syntax like propVar++ and it will correctly do a get, add 1, and then do the put.
Borland's (now Embarcadero's) C++ Builder supports this using the __property keyword. There is an example of use here (midway down the page).
For Apple programmers, Objective C++ provides non-standard support using the @property directive. See an example here.
Support using only Standard C++
In researching this article, I found a number of "solutions" to the C++ property "problem." I also found many vociferous opinions. A lot of people think that C++ has no need to be more "VB-like," while others embrace the idea wholeheartedly. Anyway, here are of few of the Standard C++ implementations that I found.
- This CodeGuru article uses a template and operator overloads to accomplish the goal. It also includes the ability to make a property that is read-only or write-only:
Implementing a Property in C++
http://www.codeguru.com/Cpp/Cpp/cpp_ mfc/articl e.php/c403 1
- This CodeProject article uses a template and creates an object for each property variable. That's an innovative idea, but the added overhead makes it rather inefficient.
Implementing Properties In C++
http://www.codeproject.com/KB/cpp/cp ppropertie s.aspx
- This CodeProject article uses a complex set of macros to do the trick, but also includes support for using the Microsoft extension if desired. You might also want to read some of the user comments, which describe and illustrate some alternative techniques.
Generic C++ Properties
http://www.codeproject.com/KB/cpp/ge nericprope rty.aspx
- The following article is a full-featured implementation, with a great description of the internal workings of its ultra-complex system of typedefs, templates, and operator overloads.
C++ implementation of the C# Property and Indexer with Accessor-Modifiers
http://www.codeproject.com/KB/cpp/cp p_property _indexer.a spx
- A user comment added to this article includes a simpler, but less versatile template-based system:
Defining Properties in C++ similar to C#
http://www.cplusplus.com/forum/gener al/8147/
- EE's own evilrix has published an article for Standards-bound C++ coders. It uses a set of macros, including token-pasting to create the get/put functions and the friend functions for operator overrides. As with most similar implementations I've seen, it lacks semantic support for ++ and += and other often-used operators.
How to add properties to standard C++ classes
http://www.experts-exchange.com/A_38 43-How-to- add-proper ties- to-st andard-C-c lasses.htm l
- This whitepaper by Lois Goldwaite proposes that property support be made available as a part of the standard C++ library. The first part of the article is an excellent introduction to the issues. And, the article includes a template-based implementation.
C++ Properties -- a Library Solution
http://www.open-std.org/jtc1/sc22/wg 21/docs/pa pers/2004/ n1615.pdf
Conclusion
I mostly agree with Lois Goldwaite that the whole issue of properties amounts to "syntactic saccharine" -- a sugar coating over the underlying nougat. I'd generally rather just add getXxxx and a putXxxx functions (and do all of the "hard work" of using them when I access certain fields) than apply a complex set of templates and macros.
However, I disagree that it should never be part of the C++ standard. If property were elevated into a first class language keyword, I'd probably use it all of the time. My advice is that if you don't mind stepping outside of the official C++ standard, and if your compiler supports the feature (even as a non-standard extension)... use it!
The usefulness of "smart fields" cannot be questioned. Data validation, source transparency, true encapsulation, and the value of hiding (and being able to change) implementation details such as OS/GUI-related API calls --- all covered with a "syntactic sucralose" to make it easy to use... sounds sweeeeet to me!
=-=-=-=-=-=-=-=-=-=-=-=-=-
If you liked this article and want to see more from this author, please click the Yes button near the:
Was this article helpful?
label that is just below and to the right of this text. Thanks!
=-=-=-=-=-=-=-=-=-=-=-=-=-
by: ericpete on 2010-10-28 at 21:33:41ID: 20930
I was asked to look at this in my capacity as the newsletter editor (it had better NOT be because of my programming skills). As you know, I'm not qualified to evaluate the code you have posted, so you can take my comments with a grain of salt if you wish.
Having said that, what I like about this article is that to someone who isn't a C++ programmer you have laid out the discussion very cleanly. It is unfortunate that it is about a subject that people with my limited experience would probably skip over in a list of articles for fear of having their eyes glaze over; the word "unfortunate" is used deliberately, because I do understand a little more about why people choose to program in the languages they do.
One question, though. In referring to the Goldwaite paper, you suggest that she wants the property support to be part of the C++ standard. You then disagree with her, saying that it should be part of the standard. Or am I missing the nature of your disagreement with her?
Nonetheless, a nice overview, and a yes vote.
ep