Home

Details on Using Classes

 

Static Members

 

Static Member Variables

As we have used them so far, you can declare many variables of the same class in a function that needs them. In the same way, you can call the same instance of a class over and over again. 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 CCylinder
{
private:
	double _radius;

public:
	CCylinder(double rad)
	{
		_radius = rad;
		Console::WriteLine(S"Class to process a cylinder");
		Cups += 1;
	}

	double Volume()
	{
		return 1.22;
	}

	__property double get_BaseArea()
	{
		return _radius * _radius * Math::PI;
	}

	int Cups;
};

int _tmain()
{
	// TODO: Please replace the sample code below with your own.
	CCylinder __gc *cyl = __gc new CCylinder(12.48);

	Console::WriteLine(S"Base Area: {0}", __box(cyl->BaseArea));
	Console::WriteLine(S"Volume:    {0}", __box(cyl->Volume()));
	Console::WriteLine(S"Cups:      {0}", __box(cyl->Cups));
	Console::WriteLine(S"");

	cyl = __gc new CCylinder(12.48);
	Console::WriteLine(S"Base Area: {0}", __box(cyl->BaseArea));
	Console::WriteLine(S"Volume:    {0}", __box(cyl->Volume()));
	Console::WriteLine(S"Cups:      {0}", __box(cyl->Cups));
	Console::WriteLine(S"");

	cyl = __gc new CCylinder(12.48);
	Console::WriteLine(S"Base Area: {0}", __box(cyl->BaseArea));
	Console::WriteLine(S"Volume:    {0}", __box(cyl->Volume()));
	Console::WriteLine(S"Cups:      {0}", __box(cyl->Cups));

	Console::WriteLine(S"");
	return 0;
}

This would produce:

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      1

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      1

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      1

Press any key to continue

In the above example, the cyl class was declare once and initialized, then it was reset two times. Notice that the value of the Cups member variable is 1 as it is set in the constructor. In a certain application, you may want to have a variable that cannot simply be reset when the variable of its class is reset. For example, if you declare a certain member variable but decide to reset it at one time in your program, you can declare a member that would not be affected by this action.

A member variable that keeps a copy of the value of its class variable is referred to as static. To declare a member variable qualified as static, type the static keyword to its left. Like all other member variables of a managed class, after declaring a static member variable, it is initialized with a 0 value. Here is an example of a static member variable:

public __gc class CCylinder
{
private:
	double _radius;

public:
	CCylinder(double rad)
	{
		_radius = rad;
		Console::WriteLine(S"Class to process a cylinder");
		Cups += 1;
	}

	double Volume()
	{
		return 1.22;
	}

	__property double get_BaseArea()
	{
		return _radius * _radius * Math::PI;
	}

	static int Cups;
};

This time, the program would produce:

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      1

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      2

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      3

Press any key to continue

When a member variable is declared in a managed class, it is initialized with 0. This is also valid for a static member variable that is automatically initialized with 0. On the other hand, after declaring a static member, you can initialize it with a value of your choice. To initialize a static member variable, when declaring it, simply assign the desired value to it. Here is an example:

public __gc class CCylinder
{
private:
	double _radius;

public:
	. . . No Change

	__property double get_BaseArea()
	{
		return _radius * _radius * Math::PI;
	}

	static int Cups = 144;
};

 This would produce:

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      145

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      146

Class to process a cylinder
Base Area: 489.304312433672
Volume:    1.22
Cups:      147

Press any key to continue

 

Static Member Variables and Static Methods

When introducing member variables and methods, we mentioned that, after they are declared, they are made available to any member of the same class. 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 CCylinder
{
private:
	double _height;

public:
	double BaseDiameter()
	{
		return Radius * 2;
	}
	
	double BaseCircumference()
	{
		return BaseDiameter() * Math::PI;
	}

	double Radius;
};

In the above class, we are able to access any member variable, in this case the Radius, in any method of the CCylinder class. We can also access any method of the class from any other method of the same class without declaring it. To access a public member of a class outside that class, you must first declare a variable of that class, then use either the period "." or the arrow "->" operator to specify the member you want to access. 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 CCylinder
{
private:
	double _height;

public:
	double BaseDiameter()
	{
		return Radius * 2;
	}
	
	double BaseCircumference()
	{
		return BaseDiameter() * Math::PI;
	}

	double Radius;
};

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CCylinder __gc *cyl = __gc new CCylinder;
	cyl->Radius = 15.48;

	Console::WriteLine(S"Cylinder Characteristics");
	Console::WriteLine(S"Radius:   {0}", __box(cyl->Radius));
	Console::WriteLine(S"Diameter: {0}", __box(cyl->BaseDiameter()));
	Console::WriteLine(S"Circumference: {0}", __box(cyl->BaseCircumference()));

    	Console::WriteLine(S"");
	return 0;
}

Notice that, if you try to access the _height member variable of the CCylinder class in the _tmain() function that is not a member of the class, you would receive an error because _height is a private member variable. Based on this, the members of a class are said to have class scope because they can be directly accessed only inside of the class.  There is an exception to this.

If you want to access a member of a class without using a declared variable of the class. You can declare the member of static. This technique allows you to access a method of a class outside of the class and without primarily declaring a variable for that class. To declare a member variable of a class and make it static, type the static keyword to its left:

public __gc class CCylinder
{
public:
	double BaseDiameter()
	{
		return Radius * 2;
	}
	
	double BaseCircumference()
	{
		return BaseDiameter() * Math::PI;
	}

	static double Radius;
};

To declare a method as static, type the static keyword to its left. It is up to you to decide what methods would be made static when creating a class. Here are two static methods:

public __gc class CCylinder
{
public:
	static double BaseDiameter()
	{
		return Radius * 2;
	}
	
	static double BaseCircumference()
	{
		return BaseDiameter() * Math::PI;
	}

	static double Radius;
};

After a member of a class has been declared as static, to access it outside of the class, you can first declare a variable and then use the period "." or the arrow "->" operator to select the member you want to access from the class. Here are examples:

// 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 CCylinder
{
public:
	static double BaseDiameter()
	{
		return Radius * 2;
	}
	
	static double BaseCircumference()
	{
		return BaseDiameter() * Math::PI;
	}

	static double Radius;
};

int _tmain()
{
    	// TODO: Please replace the sample code below with your own.
	CCylinder __gc *cyl = __gc new CCylinder;
	cyl->Radius = 15.48;

	Console::WriteLine(S"Cylinder Characteristics");
	Console::WriteLine(S"Radius:   {0}", __box(cyl->Radius));
	Console::WriteLine(S"Diameter: {0}", __box(cyl->BaseDiameter()));
	Console::WriteLine(S"Circumference: {0}", __box(cyl->BaseCircumference()));

    	Console::WriteLine(S"");
	return 0;
}

This would produce:

Cylinder Characteristics
Radius:   15.48
Diameter: 30.96
Circumference: 97.26370855514

Press any key to continue

As mentioned already, you don't have to declare a class variable in order to access a static member. You be able to access the member directly but because there are thousands of functions that are declared globally, you must first type the name of the class, followed by the "::" operator, followed by the member you want to access. Here are examples:

// 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 CCylinder
{
public:
	static double BaseDiameter()
	{
		return Radius * 2;
	}
	
	static double BaseCircumference()
	{
		return BaseDiameter() * Math::PI;
	}

	static double Radius;
};

int _tmain()
{
	// TODO: Please replace the sample code below with your own.
	CCylinder::Radius = 22.64;

	Console::WriteLine(S"Cylinder Characteristics");
	Console::WriteLine(S"Radius:   {0}", __box(CCylinder::Radius));
	Console::WriteLine(S"Diameter: {0}", __box(CCylinder::BaseDiameter()));
	Console::WriteLine(S"Circumference: {0}", __box(CCylinder::BaseCircumference()));

	Console::WriteLine(S"");
	return 0;
}

This would produce:

Cylinder Characteristics
Radius:   22.64
Diameter: 45.28
Circumference: 142.251315354546

Press any key to continue

You can also use a mix of declared and non-declared class variables to access different static members of a class. Notice that we have been calling the Write(), WriteLine(), and ReadLine() methods that are static member functions of the Console class.

this Pointer

 

Introduction

We have been able to declare variables inside of functions when needed. This type is referred to as local variable. Observe the following program:

// 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 CCylinder
{
private:
	double radius;

public:
	CCylinder()
	{
		double radius = 0.00;
	}

	double Volume()
	{
		double radius = 1.00;
		return radius;
	}

	__property double get_Radius()
	{
		double radius = 0.01;
		return radius;
	}
	__property double get_BaseArea()
	{
		return radius * radius * Math::PI;
	}
};

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

	double radius = 2.00;

	Console::WriteLine(S"");
	return 0;
}

In the above program, a variable called radius is declared as a member of a class and locally in different functions. As seen in the above Volume() method, you can declare a local variable in a member function, and the variable can have the same name as a member variable of the same class. This can create confusion. For example, in the above CCylinder() constructor or in the Volume() method, when accessing the locally declared radius member variable, neither you nor the compiler may know what radius variable you are referring to. To solve this and some other problems, each class you create automatically provides an object you can use to refer to other members of the same class. This object is called this.

The this pointer is an implicit but completely hidden member variable of a class. It behaves as a pointer declared inside the class but is never counted as one of its members. For example, if you use the sizeof operator to know the amount of space memory that a class variable is occupying, the this member would not be taken into consideration. Based on this, all of the methods of classes we have used so far had a this pointer. This also means that, when accessing members of a class inside of methods of the same class, the this pointer is implicitly used. Otherwise, you can use the this pointer to make your code (very) easy to read. Here are examples:

// 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 CCylinder
{
private:
	double radius;

public:
	CCylinder(double rad) { this->radius = rad; }

	double Diameter() {	return Radius * 2; }
	
	double Circumference()
	{
		return this->Diameter() * Math::PI;
	}

	__property double get_Radius()
	{
		return this->radius;
	}
};

int _tmain()
{
	// TODO: Please replace the sample code below with your own.
	CCylinder __gc *cyl = __gc new CCylinder(20.58);

	Console::WriteLine(S"Cylinder Characteristics");
	Console::WriteLine(S"Radius:   {0}", __box(cyl->Radius));
	Console::WriteLine(S"Diameter: {0}", __box(cyl->Diameter()));
	Console::WriteLine(S"Circumference: {0}", __box(cyl->Circumference()));

	Console::WriteLine(S"");
	return 0;
}

The this pointer would be declared as

*this;

Although this is never done (never declare this as a member variable), this declaration means that this is in fact a pointer to its class. This declaration also means that if you have to return a class from one of its methods, you must return *this. In fact the *this notation represents the object itself and therefore, gives access to the members of the class using the period operator. Therefore, the above class can use the *this object as follows:

public __gc class CCylinder
{
private:
	double radius;

public:
	CCylinder(double rad) { (*this).radius = rad; }

	double Diameter() {	return Radius * 2; }
	
	double Circumference()
	{
		return (*this).Diameter() * Math::PI;
	}

	__property double get_Radius()
	{
		return (*this).radius;
	}
};

Because this is only applied to a class, it is never used outside of the confinements of a class. For example, this is never used in a C++ main,() function because C++ doesn't allow main() to be a member of a class (some other languages like C# require that each function, including Main(), be a member of a class). Based on this, whenever you access a member variable in a method of a class, always make sure you know what variable you are accessing. Whenever in doubt, you should use the this pointer.

 

this and Related Methods

One of the biggest advantages of inheritance is a derived class inherit its primary behavior from its parent class. Based on this relationship, the this pointer provides access to all public and protected members of the base class.

Unlike regular member functions, static methods don't have a this pointer. Therefore, inside of a method of a class, don't make an attempt to call the this pointer.

 

 

Previous Copyright © 2004-2010 FunctionX, Inc. Next