Home

Reference Methods

 

Introduction

Like a regular function, a method of a class can be created to return a reference. When creating the method, make sure you type the & operator on the left of its name. When implementing the method, in most cases, you can simply return a member variable of the class that is declared with the same data type as the one that the method would return. Here is an example:

#include <iostream>

using namespace std;



class Circle

{

private:

	double rad;



public:

	Circle();

	Circle(double rad);

	double &Radius();

	double Diameter();

	double Circumference();

	double Area();

};



Circle::Circle()

	: rad(0.00)

{

}



Circle::Circle(double radius)

	: rad(radius)

{

}



double &Circle::Radius()

{

	return rad;

}



double Circle::Diameter()

{

	return rad * 2;

}



double Circle::Circumference()

{

	return this->Diameter() * 3.14159;

}



double Circle::Area()

{

	return rad * rad * 3.14159;

}



void ShowCircle(Circle &circ)

{

	cout << "\nCircle Characteristics";

	cout << "\nRadius:        " << circ.Radius();

	cout << "\nDiameter:      " << circ.Diameter();

	cout << "\nCircumference: " << circ.Circumference();

	cout << "\nArea:          " << circ.Area() << endl;

}



int main()

{

	Circle circ;

	

	ShowCircle(circ);



	return 0;

}
 

Features of Reference Methods

You may remember that a function can only be assigned to a variable. Here is an example:

class Circle

{

private:

	double Radius;

public:

	Circle(double rad) { Radius = rad; }

	double Area() { return Radius * Radius * 3.14159; }

};



int main()

{

	Circle circ(24.55);

	double a = circ.Area();



	return 0;

}

On the other hand, no value can be assigned to the name of a method. For example, the following code will not compile:

class Circle

{

private:

	double Radius;

public:

	Circle(double rad) { Radius = rad; }

	double Area() { return Radius * Radius * 3.14159; }

};



int main()

{

	Circle circ(24.55);

	double a = 0.00;

	circ.Area() = a;



	return 0;

}

In Microsoft Visual C++ 6.0, you would get the following error:

error C2106: '=' : left operand must be l-value

Error executing cl.exe.

The exception to this rule is with reference methods. If a method returns a reference, it can be assigned to a variable. In the same way, it can be assigned a value. Consider the following examples:

#include <iostream>

using namespace std;



class Circle

{

private:

	double rad;



public:

	Circle();

	Circle(double rad);

	double &Radius();

	double Diameter();

	double Circumference();

	double Area();

};



Circle::Circle()

	: rad(0.00)

{

}



Circle::Circle(double radius)

	: rad(radius)

{

}



double &Circle::Radius()

{

	return rad;

}



double Circle::Diameter()

{

	return rad * 2;

}



double Circle::Circumference()

{

	return this->Diameter() * 3.14159;

}



double Circle::Area()

{

	return rad * rad * 3.14159;

}



Circle &CreateCircle()

{

	Circle *round = new Circle();

	Circle &circ  = *round;

	double rad;



	cout << "Enter the radius of the circle: ";

	cin >> rad;



	// Assigning a value to a reference method

	circ.Radius() = rad;



	return circ;

}



void ShowCircle(Circle &circ)

{

	// Assigning a reference method to a value

	double rayon = circ.Radius();



	cout << "\nCircle Characteristics";

	cout << "\nRadius:        " << rayon;

	cout << "\nDiameter:      " << circ.Diameter();

	cout << "\nCircumference: " << circ.Circumference();

	cout << "\nArea:          " << circ.Area() << endl;

}



int main()

{

	Circle circ = CreateCircle();

	ShowCircle(circ);



	return 0;

}

Notice that a reference method is assigned a value or a value is assigned to it. In the C++ jargon, this means that a reference method can be either an L-value (left value) or an R-value (right value) in an expression.

 

Reference Methods and Accessory Member Functions

Remember that, in C++ (and many other languages), you can create a set method used to assign a value to a member variable of a class and you can create a get method to retrieve the value held by a member variable. Consider the following examples:

#include <iostream>

using namespace std;



class Triangle

{

private:

	double bas;

	double hgt;



public:

	Triangle();

	Triangle(double base, double height);



	void   setBase(const double base);

	double getBase();

	void   setHeight(const double height);

	double getHeight();



	double Area();

};



Triangle::Triangle()

	: bas(0.00), hgt(0.00)

{

}



Triangle::Triangle(double base, double height)

	: bas(base), hgt(height)

{

}



void Triangle::setBase(const double base)

{

	if( base <= 0.00 )

		bas = 0.00;

	else

		bas = base;

}



double Triangle::getBase()

{

	return bas;

}



void Triangle::setHeight(const double height)

{

	if( height <= 0.00 )

		hgt = 0.00;

	else

		hgt = height;

}



double Triangle::getHeight()

{

	return hgt;

}



double Triangle::Area()

{

	return bas * hgt / 2;

}



int main()

{

	Triangle *tri = new Triangle();



	tri->setBase(35.48);

	tri->setHeight(24.66);



	cout << "Triangle Characteristics\n";

	cout << "Base:   " << tri->getBase() << endl;

	cout << "Height: " << tri->getHeight() << endl;

	cout << "Area:   " << tri->Area() << endl;



	return 0;

}

This would produce:

Triangle Characteristics

Base:   35.48

Height: 24.66

Area:   437.468

In the earlier examples on reference methods, we demonstrated that a reference method could be assigned a value or it could be assigned to a variable. This would lead to wonder what would be their difference with accessory methods. The answer is, mostly none. Instead of using accessory set and get methods, you can replace their combination with a single reference method and get the same effect. This is demonstrated in the following program:

#include <iostream>

using namespace std;



class Triangle

{

private:

	double bas;

	double hgt;



public:

	Triangle();

	Triangle(double base, double height);



	double &Base();

	double &Height();



	double Area();

};



Triangle::Triangle()

	: bas(0.00), hgt(0.00)

{

}



Triangle::Triangle(double base, double height)

	: bas(base), hgt(height)

{

}



double &Triangle::Base()

{

	if( bas <= 0.00 )

		bas = 0.00;

	

	return bas;

}



double &Triangle::Height()

{

	if( hgt <= 0.00 )

		hgt = 0.00;

	

	return hgt;

}



double Triangle::Area()

{

	return this->Base() * this->Height() / 2;

}



int main()

{

	Triangle *tri = new Triangle();



	tri->Base() = 42.64;

	tri->Height() = 28.46;



	cout << "Triangle Characteristics\n";

	cout << "Base:   " << tri->Base() << endl;

	cout << "Height: " << tri->Height() << endl;

	cout << "Area:   " << tri->Area() << endl;



	return 0;

}

This would produce:

Triangle Characteristics

Base:   42.64

Height: 28.46

Area:   606.767

Home Copyright © 2005 FunctionX, Inc.