In short, the property has two parts:
1) m_width, the actual data storage
2) width, which is an object pretending to be the data storage.
When the user writes code like
int w = obj.width;
then he gets the Width_Prop member. Then the type conversion operator is invoked to convert the Width_Prop to an int. This operator reads the real value from m_width.
When the user writes code like
obj.width = 10;
then he assigns to the Width_Prop member, which means that the overloaded assignment operator is invoked. This operator checks the value for validity, then assigns it to m_width.
The rest is just boilerplate. The outer class and Width_Prop need mutual friendship because they access each other's private stuff. Width_Prop is non-copyable and has a private constructor so that nothing outside the outer class can get the stupid idea to create a Width_Prop object. Width_Prop needs a reference to the outer class so that it can access m_width. The constructors of the outer class need to supply this reference. And because the outer class has a non-copyable and non-assignable member, copy constructor and assignment operator cannot be auto-generated by the compiler, so you have to do that yourself. (I forgot to implement the assignment operator. I'll do that in a moment.)
As I said, lots of boilerplate, little use.
There are problems. You can't do either of these, even though the syntax looks like it should work:
Code:
int *pi = &obj.width; // Error: can't convert Width_Prop* to int*.
int &ri = obj.width; // Error: can't convert Width_Prop& to int&, or can't assign temporary to non-const reference.
Worse, some compilers actually let you do the second thing, but modifying the value then won't have any effect.
I think this is all stupid. Use a pair of accessor functions. There's not a single C++ programmer who won't understand what they're about.
Code:
int get_width() const;
void set_width(int a_width);
Names may vary depending on your convention: get_width/set_width, width/width, getWidth/setWidth, GetWidth/SetWidth. But they all mean the same.
Sometimes the setters return something, too. But since it's not entirely clear what they should return - The new value, like the assignment operator (push through)? The old value, like set_new_handler, set_unexpected_handler, and many functions in the Win32 API (push out)? Or even the outer object itself, to allow for chaining like obj.setWidth(10).setHeight(10)? - I prefer to have them return nothing and avoid the ambiguity.