Browse DevX
Sign up for e-mail newsletters from DevX


Book Excerpt: Essential Guide to Managed Extensions in C++ : Page 4

Managed Extensions for C++ are added to the Visual C++ .NET compiler to allow access to .NET Framework functionality. Visual C++ .NET is the only .NET language that can generate both native and managed code, and its rich set of features let you write managed applications for the .NET platform. This comprehensive guide to coding managed extensions for C++ was written by key members of the Visual C++ .NET compiler development teampeople who have spent most of their time implementing the language and educating others about managed C++. Read Chapter 9, ''Properties.''




Building the Right Environment to Support AI, Machine Learning and Deep Learning

How Properties Work
When you define a property by declaring a getter or a setter, the MC++ compiler "pretends" a data member is defined. This data member is called a pseudo member because it doesn't actually exist. The compiler replaces the pseudo member in your code by a call to the appropriate method which, depending on the context, is either the getter or the setter:

#using <mscorlib.dll> __gc class MyArray { //... public: //... __property int get_Length(); __property void set_Length(int); }; void IncrementLength(MyArray*pArray ) { int nLen =pArray->Length;//calls pArray->get_Length(); pArray->Length =nLen +1;//calls pArray->set_Length(nLen +1); }

Remember, we warned you in the last section that the value of the property must be passed in the last argument of the setter. Now it's time to shed some light on this situation. Here is how the compiler generates the function call for the setter: given an indexed property Address, the compiler will convert the expression

pDB->Address [S "John Smith "] ==S "Seattle ";


pDB->set_Address(S "John Smith ",S "Seattle ");

passing the value from the right side of the assignment in a last argument of the setter. That's why if this last argument expects anything else other than the new value of the property, you will not get the result you want. What if you want to increment a property using operator++? You can do that as follows:

void IncrementLength2(MyArray*pArray ) { ++pArray->Length; //compiler generates: //pArray->set_Length(pArray->get_Length()+1); pArray->Length++; //compiler generates: //int tmp;tmp =pArray->get_Length(), //pArray->set_Length(tmp +1),tmp; }

As in unmanaged C++, the post-increment operator is less efficient than the pre-increment operator—it requires a temporary variable to hold the value of the property before the increment. Hence this advice: where you can, consider using a pre-increment operator instead of a post-increment operator.

What You Cannot Do with Properties
As we said earlier, a good property behaves like a data member. Is there anything you can do with a data member but not with a property? Unfortunately, yes. Let's recall the earlier example with class Student. Consider the following:

#using <mscorlib.dll> __gc class Student { int age_; //... public: //... __property int get_Age(){return age_;} __property void set_Age(int age){age_=age;} void Birthday(); }; void IncrementAge(int*pAge ) { (*pAge)++; } void Student::Birthday() { IncrementAge(&Age );//error! }

With what you now know about properties, it should come as no surprise that this code won't work. Still wondering why? Look at the call to IncrementAge—the function expects a parameter of type int*, but the property, Age, is provided instead. What can the compiler do? The pseudo member Age can be replaced with either get_Age or set_Age , neither of which would yield the desired result. That's why taking address of a property is illegal—and results in a compile-time error.

There is also one restriction to overloading property methods. Examine the following code:

#using <mscorlib.dll> using namespace System; __gc class Product { //... }; __gc class Inventory { //... public: //... __property int get_ItemsSold(int ProductID); __property void set_ItemsSold(int ProductID,int value); __property int get_ItemsSold()__gc [];*///error! }; void SellProduct(Inventory*pInventory,int ProductID ) { pInventory->ItemsSold [ProductID ]++; }

As you can see, the method get_ItemsSold is overloaded: the first function takes one argument (), and the other one takes no arguments but returns a managed array. Now we have an ambiguity problem in the function SellProduct: how do you convert the property ItemsSold into a getter/setter function call? It is impossible to determine from the context whether either of the methods int get_ItemsSold(int)or int get_ItemsSold()__gc []should be called. So, what we want you to take away from this is an array property declaration shall not overload an indexed property.

As this chapter has shown, managed properties are easy to use because the syntax for defining them is much simpler than that of regular C++ properties. Being syntactic sugar for function calls, properties behave like data members, making code that uses them cleaner and easier to understand.

In the next chapter, we will dive into another advanced topic of MC++—operators. Like properties, operators provide a more natural way of coding by hiding function calls "under the hood." You will see how to define and use operators and user-defined conversions for value types as well as gc classes.

Reproduced from the Essential Guide to Managed Extensions for C++, by permission of Apress. ISBN 1-893115-28-3, copyright 2002. All rights reserved.

Siva Challa is a member of the Visual C++ compiler development team at Microsoft and has a Ph.D. in computer science from Virginia Tech. Although he works on compilers, he tries to interpret his 1-year-old daughters language and frequently recovers from errors by using his wifes knowledge base.

Artur Laksberg is a member of the Visual C++ compiler development team at Microsoft. When not working, he can be seen cycling the backroads of the Puget Sound, reading books (military history being his latest passion), and programming.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date