Home

Types of Properties

 

Simple 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 . . .

Practical LearningPractical Learning: Creating Simple Properties

  1. Access the StoreItem.h file
  2. To create simple properties, declare the following variables:
     
    #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);
            ~CStoreItem();
    
        private:
            long        nbr;
            __wchar_t ^ cat;
            String    ^ mk;
            String    ^ mdl;
    	    String    ^ nm;
            double      discount;
            double      price;
    
        public:
            property long        ItemNumber;
            property __wchar_t ^ Category;
            property String    ^ Make;
            property String    ^ Model;
            property String    ^ Name;
            property double      DiscountRate;
            property double      UnitPrice;
        };
    }
  3. Access the Exercise.cpp file
  4. To test the simple properties, change it as follows:
     
    #include "StoreItem.h"
    
    using namespace System;
    using namespace ElectronicsStore;
    
    static void DescribeStoreItem(CStoreItem ^ %);
    static void DescribeStoreItem(CStoreItem ^ %, const int);
    
    int main()
    {
        String ^ strTitle = L"=-= Nearson Electonics =-=\n"
    		        L"******* Store Items ******";
    
        CStoreItem ^ saleItem = gcnew CStoreItem();
    
        Console::WriteLine(L"==/==A store item with default values==/==");
        DescribeStoreItem(saleItem, 0);
        Console::WriteLine();
    
        Console::WriteLine(L"==/==A store item completely defined==/==");
        saleItem = gcnew CStoreItem();
        saleItem->ItemNumber = 513497;
        saleItem->Category   = L'T';
        saleItem->Make       = L"Uniden";
        saleItem->Model = L"8x8 Packet8 Broadband Internet Phone System";
        saleItem->DiscountRate = -10;
        saleItem->UnitPrice    =  -145.95;
        DescribeStoreItem(saleItem, 0);
    
        Console::WriteLine();
        return 0;
    }
    
    // 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);
    }
  5. Execute the application to test it. This would produce:
     
    ==/==A store item with default values==/==
    Store Item Description
    Item Number:   0
    Category:
    Make
    Model:
    Discount Rate: 0.00 %
    Unit Price:    $0.00
    
    ==/==A store item completely defined==/==
    Store Item Description
    Item Number:   513497
    Category:      T
    Make           Uniden
    Model:         8x8 Packet8 Broadband Internet Phone System
    Discount Rate: -1,000.00 %
    Unit Price:    ($145.95)
    
    Press any key to continue . . .
  6. Close the DOS window

Read-Only Properties

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.

Practical LearningPractical Learning: Using Read-Only Properties of a Class

  1. Display the StoreItem.h header file
  2. To transform the simple properties into read-only, change the file as follows:
     
    #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; }
    	}
    
            property __wchar_t ^ Category
            {
    		__wchar_t ^ get() { return cat; }
    	}
    
            property String ^ Make
            {
    		String ^ get() { return mk; }
    	}
    
            property String ^ Model
            {
    		String ^ get() { return mdl; }
    	}
    
            property String ^ Name
            {
    		String ^ get() { return nm; }
    	}
    
            property double DiscountRate
            {
    		double get() { return discount; }
    	}
    
            property double UnitPrice
            {
    		double get() { return price; }
    	}
    
        };
    }
  3. Execute the application to test it
  4. Notice that you receive many errors because of the assignments in the Exercise.cpp file
  5. Access the Exercise.cpp file and change it as follows:
     
    #include "StoreItem.h"
    
    using namespace System;
    using namespace ElectronicsStore;
    
    static void DescribeStoreItem(CStoreItem ^ %);
    static void DescribeStoreItem(CStoreItem ^ %, const int);
    
    int main()
    {
        String ^ strTitle = L"=-= Nearson Electonics =-=\n"
    		        L"******* Store Items ******";
    
        CStoreItem ^ saleItem = gcnew CStoreItem();
    
        Console::WriteLine(L"==/==A store item with default values==/==");
        DescribeStoreItem(saleItem, 0);
        Console::WriteLine();
    
        Console::WriteLine(L"==/==A store item completely defined==/==");
        saleItem = gcnew CStoreItem(513497, L'T', L"Uniden",
    		L"8x8 Packet8 Broadband Internet Phone System",
    		-10, -145.95);
        DescribeStoreItem(saleItem, 0);
    
        Console::WriteLine();
        return 0;
    }
    
    // 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);
    }
  6. Execute the application again
  7. Close the DOS window

Write-Only Properties

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 . . .

Read/Write Properties

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:

Header File: Rectangle.h
#pragma once

using namespace System;

public ref class CRectangle
{
private:
	double len;
	double hgt;

public:
	property String ^ Name;

    property double Length
    {
    	double get() { return len; }

	void set(double L)
	{
		len = L;
	}
    }

    property double Height
    {
	double get() { return hgt; }

	void set(double h)
	{
		hgt = h;
	}
    }

    property double Perimeter
    {
	double get()
	{
		return 2 * (Length + Height);
	}
    }

    property double Area
    {
	double get()
	{
		return Length * Height;
	}
    }
};
Source File: Rectangle.cpp
#include "Rectangle.h"
Source File: Exercise.cpp
#include "Rectangle.h"

using namespace System;

CRectangle ^ CreateShape()
{
	CRectangle ^ R = gcnew CRectangle;

	R->Name = L"Rectangle";
	R->Length = 42.06;
	R->Height = 27.92;
	return R;
}

void ShowCharacteristics(CRectangle ^ %recto)
{
	Console::WriteLine(L"Shape Characteristics");
	Console::WriteLine(L"Name:      {0}", recto->Name);
	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 = CreateShape();

	ShowCharacteristics(rect);

	Console::WriteLine();
	return 0;
}

This would produce:

Shape Characteristics
Name:      Rectangle
Length:    42.06
Perimeter: 139.96
Area:      1174.3152

Press any key to continue . . .
 

Practical LearningPractical Learning: Using Read/Write Properties of a Class

  1. Access the StoreItem.h header file
  2. To complete the properties of the class, change the file as follows:
     
    #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; }
    	}
        };
    }
  3. Access the Exercise.cpp file and change it as follows:
     
    #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);
    }
  4. Execute the application to test it. Here is an example:
     
    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 . . .
    TV Set
  5. Close the DOS window

Previous Copyright © 2006 FunctionX, Inc. Next