Types of Properties |
|
A property is primarily a member variable of a class. To create one, you can simply precede the data type of a member variable with the property keyword. Here is an example: #pragma once public ref class CRectangle { private: double len; double hgt; public: CRectangle(double l, double h); public: property String ^ Name; }; After creating a property, you can access it outside of its class like you would any member variable. You can first declare a variable of the class and then use the period operator to access the property. Here is an example: #include "Rectangle.h" using namespace System; void ShowCharacteristics(CRectangle %recto) { Console::WriteLine(L"Shape Characteristics"); Console::WriteLine(L"Name: {0}", recto.Name); } int main() { CRectangle rect(24.58, -22.16); rect.Name = L"Rectangle"; ShowCharacteristics(rect); Console::WriteLine(); return 0; } Or you can create a handle to the class and use the arrow operator to access the property. Here is an example: #include "Rectangle.h" using namespace System; void ShowCharacteristics(CRectangle ^ %recto) { Console::WriteLine(L"Shape Characteristics"); Console::WriteLine(L"Name: {0}", recto->Name); } int main() { CRectangle ^ rect = gcnew CRectangle(24.58, -22.16); rect->Name = L"Rectangle"; ShowCharacteristics(rect); Console::WriteLine(); return 0; } This would produce: Shape Characteristics Name: Rectangle Press any key to continue . . .
One of the roles of a property is to allow the other members of the class or the other class and functions of an application to find out what value the property is holding. Such a property is referred to as "getter". The formula to create a property that provides the value of its member variable is: modifier property type property_name { modifier type get(); } Notice that the property is created like a namespace: it has a body and curly brackets but no parentheses like a function. In the body of the property, there is a type of method named get. This name is required. Because the property is meant to return a value, the get() method returns a data type. Because get() is a method, it must have a body delimited with curly brackets. Here is an example from our CRectangle class: public ref class CRectangle { private: double len; double hgt; public: property double Length { double get() {} } }; Use the body of the get method to implement the necessary behavior of the property getter. The simplest way consists of returning its corresponding private member variable. Here is an example: public ref class CRectangle { private: double len; public: property double Length { double get() { return len; } } }; When a property includes only a get() method, such a property is referred to as a read-only because the outside classes and functions can only retrieve the value of the property but they cannot change it. A classic example is the area of a rectangle. There is no need or reason for outside classes or functions to modify this value. They can only retrieve it if they need it. For this reason, you can create such a method as read-only. Here is an example: public ref class CRectangle { private: double len; double hgt; public: CRectangle(double l, double h); public: property double Length { double get() { return len; } } property double Area { double get() { return len * hgt; } } }; After creating a property, you can access it like you would any member variable. You can first declare a variable of the class, a pointer to the class, or its handle, and use either the period or the arrow operator. Here is an example: using namespace System; public ref class CRectangle { private: double len; double hgt; public: CRectangle(); CRectangle(double l, double h); public: property double Length { double get() { return len; } } property double Perimeter { double get() { return 2 * (len + hgt); } } property double Area { double get() { return len * hgt; } } }; CRectangle::CRectangle() : len(0.00), hgt(0.00) { } CRectangle::CRectangle(double l, double h) : len(l), hgt(h) { } void ShowCharacteristics(CRectangle ^ %recto) { Console::WriteLine(L"Rectangle Characteristics"); Console::WriteLine(L"Length: {0}", recto->Length); Console::WriteLine(L"Perimeter: {0}", recto->Perimeter); Console::WriteLine(L"Area: {0}", recto->Area); } int main() { CRectangle ^ rect = gcnew CRectangle(24.58, -22.16); ShowCharacteristics(rect); Console::WriteLine(); return 0; } This would produce: Rectangle Characteristics Length: 24.58 Perimeter: 4.84 Area: -544.6928 Press any key to continue . . . In the same way, you can create as many read-only properties as you want. Notice that the perimeter of our rectangle appears to be less than the length. Furthermore, the area is negative. Both values don't make sense. A getter property doesn't have to directly produce the value of the member variable. It can use a mechanism to validate a value that its corresponding member variable is holding. If the value is admissible, you can use it. If the value is not acceptable, you can either reject it or provide an appropriate alternative.
As mentioned previously, if you create a private member variable, the outside classes and functions cannot access it to influence its value. If you still want these other classes and functions to modify the value of the member variable, you can create a property to stand in the middle. The outside classes and functions can then submit a value to the property, and the property would be in charge of assigning it to the corresponding member variable. The formula to create such a property is: modifier property type property_name { modifier void set(type); } This type of property is used to receive values for a member variable. Because it doesn't return a value, it is created as void. The method that actually handles the "transaction" is named set. The value that is submitted to the property is passed as an argument to the set() method. Because set is a method, it must have a body. Here is an example: public ref class CRectangle { private: double hgt; public: property double Height { void set(double h) { } } }; In the body of the set() method, define the necessary behavior of the property. At a minimum, you can assign the argument to the corresponding member variable. Here is an example: public ref class CRectangle { private: double hgt; public: property double Height { void set(double h) { hgt = h; } } }; Once again, to access the property from an external object or function, you can use the appropriate operator (. or ->) as if it were a member variable. Here is an example: using namespace System; public ref class CRectangle { private: double len; double hgt; public: CRectangle(); CRectangle(double l, double h); public: property double Length { double get() { return len; } } property double Height { void set(double h) { hgt = h; } } property double Perimeter { double get() { return 2 * (len + hgt); } } property double Area { double get() { return len * hgt; } } }; CRectangle::CRectangle() : len(0.00), hgt(0.00) { } CRectangle::CRectangle(double l, double h) : len(l), hgt(h) { } void ShowCharacteristics(CRectangle ^ %recto) { Console::WriteLine(L"Rectangle Characteristics"); Console::WriteLine(L"Length: {0}", recto->Length); Console::WriteLine(L"Perimeter: {0}", recto->Perimeter); Console::WriteLine(L"Area: {0}", recto->Area); } int main() { CRectangle ^ rect = gcnew CRectangle(24.58, 22.16); rect->Height = 35.64; ShowCharacteristics(rect); Console::WriteLine(); return 0; } This would produce: Rectangle Characteristics Length: 24.58 Perimeter: 22.12 Area: 876.0312 Press any key to continue . . .
We have seen that a property provides a valuable relationship between a private member variable of a class and the outside world. As such, it can both receive values for the member variable and provide values to the outside world. This means that a property can be meant to both read from and write to its corresponding member variable. Such a proeprty is referred to as read/write. To create a read/write property, you must implement both the get() and the set() methods of the property. When a property is read/write, its set() method can be used to validate the values that are submitted to the property. The get() method can then be used to present the current value of the property to the external classes and functions. It is important to note that the other members of the class can also access the property. Here are examples of read/write properties:
This would produce: Shape Characteristics Name: Rectangle Length: 42.06 Perimeter: 139.96 Area: 1174.3152 Press any key to continue . . . |
Practical Learning: Using Read/Write Properties of a Class |
#pragma once using namespace System; namespace ElectronicsStore { public ref class CStoreItem { public: // An item whose characteristics are not (yet) known CStoreItem(void); // An item that is known by its make, model, and unit price CStoreItem(long itmNbr, String ^ make, String ^ model, double unitPrice); // An item that is known by its name and unit price CStoreItem(long itmNbr, String ^ name, double unitPrice); // An item completely defined CStoreItem(long itmNbr, __wchar_t category, String ^ make, String ^ model, double discountRate, double unitPrice); ~CStoreItem(); private: long nbr; __wchar_t ^ cat; String ^ mk; String ^ mdl; String ^ nm; double discount; double price; public: property long ItemNumber { long get() { return nbr; } void set(long n) { this->nbr = n; } } property __wchar_t ^ Category { __wchar_t ^ get() { return cat; } void set(__wchar_t ^ n) { this->cat = n; } } property String ^ Make { String ^ get() { return mk; } void set(String ^ m) { this->mk = m; } } property String ^ Model { String ^ get() { return mdl; } void set(String ^ m) { this->mdl = m; } } property String ^ Name { String ^ get() { return nm; } void set(String ^ n) { this->nm = n; } } property double DiscountRate { double get() { return discount; } void set(double d) { this->discount = d; } } property double UnitPrice { double get() { return price; } void set(double p) { this->price = p; } } }; } |
#include "StoreItem.h" using namespace System; using namespace ElectronicsStore; CStoreItem ^ CreateStoreItem(); static void DescribeStoreItem(CStoreItem ^ %); static void DescribeStoreItem(CStoreItem ^ %, const int); int main() { String ^ strTitle = L"=-= Nearson Electonics =-=\n" L"******* Store Items ******"; CStoreItem ^ saleItem = CreateStoreItem(); Console::WriteLine(L""); DescribeStoreItem(saleItem, 0); Console::WriteLine(); return 0; } CStoreItem ^ CreateStoreItem() { long number; __wchar_t ^ category; String ^ make; String ^ model; double discount; double price; Console::WriteLine(L"To create a store item, enter its information"); Console::Write(L"Item Number: "); number = long::Parse(Console::ReadLine()); Console::WriteLine(L"Category"); Console::WriteLine(L"A - Audio Cables"); Console::WriteLine(L"B - Instructional and Tutorials (Books)"); Console::WriteLine(L"C - Cell Phones and Accessories"); Console::WriteLine(L"D - Bags and Cases"); Console::WriteLine(L"H - Headphones"); Console::WriteLine(L"I - Instructional and Tutorials (VHS & DVD)"); Console::WriteLine(L"M - Digital Cameras"); Console::WriteLine(L"O - Cables and Connectors"); Console::WriteLine(L"P - PDAs and Accessories"); Console::WriteLine(L"T - Telephones and Accessories"); Console::WriteLine(L"S - Surge Protector"); Console::WriteLine(L"V - TVs and Videos"); Console::Write(L"Your Choice? "); category = __wchar_t::Parse(Console::ReadLine()); Console::Write(L"Make "); make = Console::ReadLine(); Console::Write(L"Model: "); model = Console::ReadLine(); Console::Write(L"Discount Applied (Enter 0 to 100, 0 if no discount): "); discount = double::Parse(Console::ReadLine()); Console::Write(L"Unit Price: "); price = double::Parse(Console::ReadLine()); CStoreItem ^ sItem = gcnew CStoreItem; sItem->ItemNumber = number; sItem->Category = category; sItem->Make = make; sItem->Model = model; sItem->DiscountRate = discount; sItem->UnitPrice = price; return sItem; } // This function is used when an item is specified by its make and model void DescribeStoreItem(CStoreItem ^ %item) { Console::WriteLine(L"Store Item Description"); Console::WriteLine(L"Item Number: {0}", item->ItemNumber); Console::WriteLine(L"Category: {0}", item->Category); Console::WriteLine(L"Make {0}", item->Make); Console::WriteLine(L"Model: {0}", item->Model); Console::WriteLine(L"Name: {0}", item->Name); Console::WriteLine(L"Discount Rate: {0:P}", item->DiscountRate); Console::WriteLine(L"Unit Price: {0:C}", item->UnitPrice); } // This function is used when an item is specified by its name void DescribeStoreItem(CStoreItem ^ %item, const int) { Console::WriteLine(L"Store Item Description"); Console::WriteLine(L"Item Number: {0}", item->ItemNumber); Console::WriteLine(L"Category: {0}", item->Category); Console::WriteLine(L"Make {0}", item->Make); Console::WriteLine(L"Model: {0}", item->Model); Console::WriteLine(L"Discount Rate: {0:P}", item->DiscountRate); Console::WriteLine(L"Unit Price: {0:C}", item->UnitPrice); } |
To create a store item, enter its information Item Number: 666802 Category A - Audio Cables B - Instructional and Tutorials (Books) C - Cell Phones and Accessories D - Bags and Cases H - Headphones I - Instructional and Tutorials (VHS & DVD) M - Digital Cameras O - Cables and Connectors P - PDAs and Accessories T - Telephones and Accessories S - Surge Protector V - TVs and Videos Your Choice? V Make Maxent Model: MX-42VM11 Discount Applied (Enter 0 to 100, 0 if no discount): 5 Unit Price: 1250.50 Store Item Description Item Number: 666802 Category: V Make Maxent Model: MX-42VM11 Discount Rate: 500.00 % Unit Price: $1,250.50 Press any key to continue . . . |
|
||
Previous | Copyright © 2006-2016, FunctionX, Inc. | Next |
|