Logo

Visual C++ Keywords: __property

 

Introduction

In object oriented programming languages, and C++ is one of them, a member variable is a variable declared in a class. Most programmers believe that it is usually a good idea to isolate the member variables of a class in a private section. Once this is done, if you still want to give access of the member variable to external classes, you must provide a means of doing that. There are usually two functions used to do this, called a setter and a getter.

When a member variable of a class has been declared as private, to allow external classes and functions to change the value of such a member variable, you usually use a void method whose name, by habit, starts with set. Such a method usually takes one argument that is the same type as the member variable whose value it would be used to validate. On the other hand, to allow external functions and classes to access the value held by a private member variable of a class, you can use a method whose name, by convention, starts with get. The function should return the same type of value as the member variable used.

 

Managed C++ Properties

When an external function or class needs access to the value held by the member variable, it would call either the get or the set method, depending on the necessary operation. To provide an alternative to this problem, instead of calling different methods to perform this transaction, Managed C++ introduces the notion of property.

In reality, properties have been here for a while, just not in Microsoft (Visual) C++. For example, they were used in Visual Basic <= 6. They were also highly used in Borland C++ Builder and Borland Delphi.

Here is an example of a class:

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;

public __gc class CSquare
{
private:
	double side;

public:
	CSquare(double s) { side = s; }
	virtual ~CSquare() {}
public:
	double Perimeter() { return 4 * side; }
	double Area() { return side * side; }
};

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CSquare __gc *Sqr = __gc new CSquare(-25.55);

	Console::WriteLine(S"Square Characteristics");
	Console::WriteLine(S"Area:      {0}", __box(Sqr->Area()));
	Console::WriteLine(S"Perimeter: {0}", __box(Sqr->Perimeter()));
    	Console::WriteLine(S"");
	return 0;
}

This would produce:

Square Characteristics
Area:      652.8025
Perimeter: -102.2

Press any key to continue
 

In Managed C++, to create a property, you use the __property keyword and the compiler would generate the corresponding member variable for you, provided you follow some rules. To provide a method that allows external functions and classes to access the value of the member variable, you can declare a property whose name starts with get_. This method can simply be used to return the value of the member variable. Here is an example:

public __gc class CSquare
{
private:
	double side;

public:
	CSquare(double s) { side = s; }
	virtual ~CSquare() {}
public:
	double Perimeter() { return 4 * side; }
	double Area() { return side * side; }

public:
	__property double get_Side() { return side; }
};

After this declaration, the compiler would create an internal member variable whose name is the string on the right side of get_. For this reason, the string you try after get_ must be different from the member variable whose property you are creating. As C++ is case-sensitive, we are allowed to simply change the case of the first letter. Thus we used Side.

So, after this declaration, a new member variable called Side is created and you can use outside of the class as you see fit. Here is an example:

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;

public __gc class CSquare
{
private:
	double side;

public:
	CSquare(double s) { side = s; }
	virtual ~CSquare() {}
public:
	double Perimeter() { return 4 * side; }
	double Area() { return side * side; }

public:
	__property double get_Side() { return side; }
};

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CSquare __gc *Sqr = __gc new CSquare(25.55);

	Console::WriteLine(S"Square Characteristics");
	Console::WriteLine(S"Side:      {0}", __box(Sqr->Side));
	Console::WriteLine(S"Area:      {0}", __box(Sqr->Area()));
	Console::WriteLine(S"Perimeter: {0}", __box(Sqr->Perimeter()));
    	Console::WriteLine(S"");
	return 0;
}

To create a method that would be used to receive and validate values from outside as their may be assigned to the member variable, you can declare a void method whose name starts with set_. Here is an example:

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;

public __gc class CSquare
{
private:
	double side;

public:
	CSquare() {}
	virtual ~CSquare() {}
public:
	double Perimeter() { return 4 * side; }
	double Area() { return side * side; }

public:
	__property void set_Side(double S) { side = S; }
	__property double get_Side() { return side; }
};

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CSquare __gc *Sqr = __gc new CSquare;
	
	Sqr->Side = -25.55;

	Console::WriteLine(S"Square Characteristics");
	Console::WriteLine(S"Side:      {0}", __box(Sqr->Side));
	Console::WriteLine(S"Area:      {0}", __box(Sqr->Area()));
	Console::WriteLine(S"Perimeter: {0}", __box(Sqr->Perimeter()));
    	Console::WriteLine(S"");
	return 0;
}

    

This would produce:

Square Characteristics
Side:      -25.55
Area:      652.8025
Perimeter: -102.2

Press any key to continue

Notice that we intentionally specified a negative value for the side of the square, which is unpractical. The beauty of using a property is that its methods can be used to validate the values that are assigned to it. In our example, you can use the set method to validate such values and decide whether or when they should be rejected. Here is an example whose property is equipped to validate employees' salaries:

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;

public __gc class CEmployee
{
private:
	double HourlySalary;

public:
	CEmployee() {}
	virtual ~CEmployee() {}

public:
	__property void set_Salary(double S);
	__property double get_Salary() { return HourlySalary; }
};

void CEmployee::set_Salary(double S)
{
	if( S <= 8.55 )
		HourlySalary = 8.55;
	else
		HourlySalary = S;
}

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CEmployee __gc *Empl = __gc new CEmployee;
	
	Empl->Salary = 6.25;

	Console::WriteLine(S"Employee's Information");
	Console::WriteLine(S"Hourly Salary: {0}", Empl->Salary.ToString("C"));
	
    	Console::WriteLine(S"");
	return 0;
}
 This would produce
Employee's Information
Hourly Salary: $8.55

Press any key to continue

Static Properties

As opposed to regular properties, you can also create a static property. To do this, start the declaration of the member variable with the static keyword. If you do this, the methods that process the property must also be created as static, otherwise, you would receive an error. Here is an example:

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;

public __gc class CEmployee
{
private:
	static double HourlySalary;

public:
	CEmployee() {}
	virtual ~CEmployee() {}

public:
	__property static void set_Salary(double S);
	__property static double get_Salary() { return HourlySalary; }
};

void CEmployee::set_Salary(double S)
{
	if( S <= 8.55 )
		HourlySalary = 8.55;
	else
		HourlySalary = S;
}

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CEmployee __gc *Empl = __gc new CEmployee;
	
	Empl->Salary = 6.25;

	Console::WriteLine(S"Employee's Information");
	Console::WriteLine(S"Hourly Salary: {0}", Empl->Salary.ToString("C"));
	
    	Console::WriteLine(S"");
	return 0;
}

Related Subject

static

 

 


Home Copyright © 2004-2010 FunctionX, Inc.