C++ Properties

Introduction

This article discusses how to implement C#-like properties in Visual C++ 6 or above. This article assumes that the reader has enough knowledge in the C++ language to understand the code (though the code snippet will be thoroughly explained). It is recommended that the reader understands macros, classes, functions, and typedefs; however, this code is available for anyone to use.

Background

If you are a new C++ or C# programmer, then properties may be a new concept. Properties are simply a convenient way of defining a getter and a setter for a given member variable. A getter is a member function that returns the literal value of the member variable that the property represents. The setter sets the literal value of the member variable that the property represents, but does not return a value. Properties in C# typically look like the following:

privateint _x;
publicint x
{
get
{
return _x;
}
set
{
_x = value;
}
}

Of course, get designates the getter and set designates the setter. Within the setter, a variable labeled value exists that represents the rvalue of an assignment statement that involved your property. For example, in the following code snippet, the value variable would contain the value 50.

someObject.x = 50;

When the property is assigned a value, as in the above example, the setter member function is called and passed the rvalue as an argument to a parameter labeled value. Of course, the simplicity of properties allow us to not worry about the definition of these member functions and hides the actual calling of the function from us. We simply declare the getters and setters using the get and set keywords in C#.

Properties in C++

Unfortunately, C++ does not natively support properties. Properties in C++ involve writing out each function for each setter and getter. For example, the following code implements the same property as above, but in C++.

In order to use the setter and getter, we simply call the corresponding member function.

someObject.setX(50);
int x = someObject.getX();

The above code is perfectly fine and many people prefer these setters and getters as opposed to the C#-styled ones; however, there also exist many people who want C#-styled properties in C++. Because of this, Visual C++ 6.0 and above decided to implement a property declaration attribute.

The above code allows us to tell Visual C++ that we want setFunction to be called every time property-name is assigned to. Conversely, we want getFunction to be called every time we need to get the value of property-name. Of course, we still have to define those member functions, but this brings us much closer to implementing C#-style properties.

(A small note to non-Visual C++ users: implementing these properties is possible; however, it requires a much higher level or work and this article does not address it.)

The Implementation

Of course our C++ implementation will not be the exact syntax as C# properties for obvious reasons, but nonetheless it is a close representation. Below is the only code you will need in order to implement properties in Visual C++.

At first sight, this code may look frightening, but fear not. The above code is extremely easy to use. To declare a property using these macros, we simply use one of the PROPERTY macros. Below is a sample implementation of the sample property used earlier.

When we assign a value to the <code>x property, the rvalue (which is 50 in this example) is assigned to the variable value, which is accessible in the setter. The code within the setter is then executed. When we get the value of the property, the code within our getter is executed and a value is returned (in this case, the value of _x).

Read-Only, Write-Only, and Access Modifiers

The above code natively supports read-only, write-only, and access-modified properties. Each of the different types of properties have their own uses. For example, a read-only property should only be used if neither the parent class nor any object accessing the property does not need to write to the property. Conversely, write-only should only be used if neither the parent class nor any object accessing the property does not need to read from the property. In order to use read-only and write-only properties, we simply use the corresponding macro and only define the corresponding setter or getter. Below is an example of each.

Typically, neither read-only nor write-only properties are used. It is much more common to change the access-modifier of a property. Changing the access modifier of a property simply means to make it public, private, protected, etc. It is common for read-only properties to be implemented by simply making the setterprivate. However, the getter and setter do not need to be declared with the same access-modifier. For example, the getter can be public while the setter can be private. Likewise, the getter can be private and the setter can be public.

Full Example

When learning any new concept, it helps to see a fully working example.

The above code works with any Visual C++ version above 6.0. It does not need any additional dependencies -- as the section title states, it is a full example.

How It Works

Now let us move on to the nitty-gritty. The way these properties actually work lie in the magic of C++ macros. Let us take our original C++ property example and see what our macros would actually generate.

The above code is not what the compiler actually sees after preprocessing is complete. We must replace our PROPERTY, GET, and SET with the expanded form of the macro. The expanded version would look like the following:

As you can see, our GET and SET macros expand to member functions, just like they do in C#. However, this is hidden from us when we use our macros so it appears more C#-like.

Conclusion

Many people seem to argue about whether it is better to use properties or simply use getter and setter member functions in C++. The simple fact is that both are using member functions to perform the getting and setting, and as such, neither have any runtime performance gain over the other -- they are exactly the same.

Microsofts approach to properties for native Visual C++ development allows the property to be used like a member (assuming proper implementation of the accessor and mutator of course) whereas the C# implementation has the restriction
"A property or indexer may not be passed as an out or ref variable".

What is wrong with it? When other languages are offering elegant solutions, why C++ cannot?
When you can use [] operator of vector, to read and write elements of vector, which is just a function call; why disagree the elegance and usefulness of C++ properties? Make a read-only property, and avoid modification to data, which cannot be done with a public variable. No function call is required - but safety is enforced.

People who know and advocate positive about auto keyword in C++0x, would (should) appreciate this stuff. Neither auto nor properties introduce any performance drawbacks - auto is at compile time, the property-call is replaced with given function at compile time, there is no run-time type detection for auto; and there is no one-more-level of call to actual function (which is anyway applicable to function-pointers!).

When the absurd operator –>* can be overloaded, which hasn't proven the importance of it being overloadable to me yet, why can't properties be made part of standard C++ ??

They could, but every vendor who comes up with proprietary extensions inhibits the set of choices available to the standards committee when deciding tyo do so. Microsoft should have lobbied for a language change, rather than do this.

What do templates have to do with this? If you are referring to taking a cross-platform approach and implementing properties by means of a templated class, then you should re-read the article, because I clearly point out that this is for Visual C++ only. The template version is slower because it requires a double function call (if the compiler doesn't inline the first one), and multiple moves of a reference. My approach, which takes advantage of Visual C++ specific features, is faster because the get and set is literally replaced with a single function call. There is no passing around references and no instantiating classes.

If you are referring to the standard template library, what does that (again) have to do with this? The two aren't even remotely related. Perhaps you misunderstood my usage case. It was not supposed to be an implementation of the std::vector class, if that is what you thought. It was supposed to be an example implementation of an extremely basic math 2D vector class, something that the STL does not provide. Other than that, I don't know what the STL (or even the C standard library) has to do with my article.

So, I am entirely clueless as to what you mean by your post. Could you please elaborate?

The reason I didn't use the same template approach as others was because I took advantage of Microsoft specific features, and because of that, it is a bit faster (a tiny tiny tiny bit) and not as much work is required to add a property to a class. So now I beg the question, are you arguing that the use of preprocessor macros don't belong in C++, and if so, why does that belong here? I find it rather petty. I do agree with you that macros aren't the cleanest and most friendly choice, but it provides for a cleaner and more consistent declaration layout of properties on the user's end.

I have a friend who loves repair and sometimes rebuild second world war military vehicles. It implies good knowledge of mechanics and other car building skills (for seats etc...). He is not an army provider

Using preprocessor macros for generic programming in C++ may be an interesting and challenging occupational activity, as long as you don't aim to be a software provider in the 2010s.

Have fun
AR

When the wise (person) points at the moon the fool looks at the finger (Chinese proverb)

According to that article, Bjarne Stroustrup says this about properties:

"If we find that a set of classes cannot support the ideal notion of a "property" well enough for our taste, we should not rush to add "properties" to the language. Instead, we should determine how to improve the class and template mechanisms to allow a library builder to closely approximate the ideal of properties."

Bassically this is saying that C++ does not provide an ideal solution for properties through the STL or templates and that we should modify the entire language to accomidate properties. I honestly don't think that C++ could be updated in any way to support true properties without actually adding properties to the language. Although the real motivation for Microsoft properties is to allow easier interop with COM, Microsoft's solution is by far more elegent than any other hacked together solution provided thus far. Sure, each property can be a class its self; but is that really practical and worth it?

You missed the previous sentences :For example, "properties" is a useful application concept that I don't think has a place in a general-purpose programming language. The concept is easily supported in Standard C++ through a set of classes.

I don't see in this article any example of class (or set of classes) needing the support of the ideal notion of a "property" and unable to fulfill that need with the facilities of the C++ Standard Library (which by the way is much larger than STL), not speaking of the new language constructs and library additions in C++0x.

Actually I never met such a case, sorry
AR

When the wise (person) points at the moon the fool looks at the finger (Chinese proverb)

That is because there is not a need for properties. Someone can very easily just implement a GetProperty and SetProperty method, as I discussed in the article. And I already explained to you why I did not use a series of templated classes.

I wouldn't say that exactly. It addresses people's want for properties in C++, which it does not currently have. The issue is that C++ does not have built in properties (neither in the Standard Library nor in the language itself). The solution to this issue is my article. Regardless of whether or not there is a need for properties in (Visual) C++, there is definitely a "want".