Now all I needed to do was derive my window class from the CWndProperties template - passing in the class that I originally derived my class from and that was it: <PRE lang=c++>class CNewTreeCtrl : public CWndProperties<CTreeCtrl>
...
CNewTreeCtrl wndTree;
...
wndTree.wShow = false; // this hides the window
wndTree.wShow = true; // this shows the window
wndTree.wShow = !wndTree.wShow // this toggles the windows visibility

Benefits

As a generic solution, this will work on different machines with different compilers. It can also reduce the API/framework that someone new to (let's say) MFC might need to learn. It is backwards compatible with classes already defined. And, in my opinion, once established the code will look cleaner and easier to read.

Problems

OK, so there are a few problems. First, the generic solution still uses at least 1 byte per property; and on Visual C++ it rounds up to the next 4 byte boundry. Second, the generic solution is not able to do property arrays.

Conclusion

The Collective is a company that makes video games that run on multiple platforms. The use of generic properties is appealing, but will likely have limited use within areas that need to be optimized. I know that I'll use them in the Tools department, but it's adoption in other departments will need to be limited to classes where every ounce of speed or memory is not an issue.

Revision history

June 1st 2002 - Initial revision. June 4th 2002 - Removed dependency on the (4 byte) pThis variable for every property; it now only requires 1 byte per property. Thanks to Matthias Mann who made this suggestion in his comments.

However, if you recognize that your struct/class on which you want to add properties already has some "real" field, then you can do the following trick to add an unlimited number of properties at a cost of 0-bytes.

In addition it's better that the callee returns the reference to the property (the nested class) back to the caller and not a copy of field of the wrapper class. (Does not work with types which have no copy-constructor).

Additionally the nested class' should be implemented each as a proxy class which always behave like the appropriate type. (See design pattern for proxy class).

Regarding your implementation, it is valid if all you want to do is wrap a variable to limit read or write. Your system would require more implementation to resolve wrapping random functions which is what my article dealt with.

I suggest a different way to implement properties in C++. Why not develop a simple preprocessor program that parses C++ source and substitutes property read accesses by calls to the get function, and write accesses to the set function? There would be a property declaration syntax that can be Microsoft's, Borland's or a new one.

It would produce a new source on the fly that can go to any compiler. And there would be no runtime overhead at all.

Anyway I would like that extension to be standard, but standard C++ defenders don't like the idea

The only real problem with this that I see is that which plagues any solution built on a pre-processor.

1. Parsing C++ is non-trivial at best, making a "simple preprocessor" something of an oxymoron.

2. Pre-Processing, while flexible is also often frowned upon, primarily, I think because of * It's impact on the build cycle (another tool which must be inserted into the compile / link chain) * The possibility of introducing errors in the pre-process step * That the resulting code is arguably no longer C++ (since adding non-standard extensions is the purpose of pre-processing), which can confuse developers not familiar with the pre-processor (the old "don't change the language syntax" rule)).

Of course, I don't necessarily agree that pre-processing is "bad". Both the built in pre-processor, and templates (which can be viewed as a type of pre-processing done by the compiler) are some of C++'s more powerful assets.

I know that the QT library from Trolltech uses a custom pre-processor (MOC) to add features that are not normally associated with C++ (including event handling and some introspection, I believe), but it seems that often pre-processing based solutions are criticized within the development community.

I've run into features I'd like to add to the language that pretty much seem to require pre-processing to solve in an elegant fashion (effective Design By Contract Support for one), but the effort of making sense of C++ syntax has always stopped me from pursuing these efforts very far.

Ultimately, unless you are a compiler writer, parsing C++ in anything but a stupid "replace this pattern with that pattern" fashion is generally more trouble then it's worth. It's one of the disadvantages of the C++ language that it is non-trivial to write "little helper tools".

There are some packages starting to crop up online now (don't feel like digging up links) which look promising for the future in this area. By acting as parsing front-ends and allowing you to manipulate the resulting internal code structure, they could make the parsing problem moot, but I have yet to spend much actual time checking them out.

You now have a pointer to your containing class. It's a save way. You must only change your makros so that say know the name of your class and the anme of the property. This has also the advantage that you replace a memory access to a single substraction

Mozilla uses it in it's crossplatform code (XPCOM) and it runs under a huge number of OSes and compiler.

It work on the fact the a variable must be placed somewhere in the byterange of an object. It also works for structurs that has no size. But you must ensure that the classname and variablename is right. It does only work with structs/classes because of the this pointer. You can place a assertion in it:

ASSERT(&pMyClass->m_Property == this);

PS: I've also used this method in multiple inheritens situations with templates - works great.