Month: June 2015

The Class User Type

A class is a user-defined type with both data and method members. A variable of the class type is called an object. A class’s members are partitioned into three separate access levels, public, private, and protected. The private members of a class can be accessed only by that class’s member functions. The public members of a class can be accessed by any part of the program that has an object of the class in scope. Protected members are in between these two, as they can be accessed by derived classes.

A class declaration describes a new data type. A class declaration begins with the reserved word class followed by the name of the class. The members are then listed in the class body that follows, which is enclosed by curly braces and terminated with a semicolon. The reserved words public and private separate the class into public and private sections. The data members are described in the same manner as variables, and the methods are described as functions.

#ifndef CRECTANGLE_H
#define    CRECTANGLE_H

class CRectangle{

private:
    double _length;
    double _width;
public:
    //constructor
    Rectangle(double length, double width);
    //getters and setters
    double GetLength(void);
    void SetLength(double length);
    double GetWidth(void);
    void SetWidth(double width);
    
    double Perimeter(void);
    double Area(void);

};

#endif    /* CRECTANGLE_H */

The class constructor is the function without a return value that has the same name as the class. A constructor can be passed parameters that are used to initialize the data members of the class. A class declaration does not have to include a constructor. However, supplying one or more class constructors insures that any objects are initialized with the necessary state for executing its methods.

We need to provide a definition for each method in the class declaration. Typically, we want to define these methods outside the class body. We place the class name, followed by a double colon, immediately in front of the class method name. The double colon symbol is called the scope resolution operator, an indicates that the function belongs to the scope of the class.

#include "CRectangle.h"

//constructor
CRectangle::CRectangle(double length, double width)
{
 _length = length;
 _width = width;
}

double CRectangle::GetLength(void)
{
 return _length;
}

void CRectangle::SetLength(double length)
{
 _length = length;
}

double CRectangle::GetWidth(void)
{
 return _width;
}

void CRectangle::SetWidth(double width)
{
 _width = width;
}

double CRectangle::Perimeter(void)
{
 return _width * 2 + _length * 2;
}

Declaring an object of a class type creates an instance of that class. The declaration instantiates an object of the class type and automatically calls the the class constructor. If no class constructor has been explicitly defined, the compiler provides a default constructor.

Objects can be assigned to one another easily. Unless otherwise specified with a customized assignment operator, object assignment is accomplished via a bitwise copy of data members.

#include <iostream>
#include "CRectangle.h"

using namespace std;

int main()
{
 CRectangle rec01(10, 30);
 CRectangle rec02(50, 22);

 cout << rec01.GetWidth() << " " << rec01.GetLength() << endl;
 cout << rec02.GetWidth() << " " << rec02.GetLength() << endl;

 rec01 = rec02;

 cout << rec01.GetWidth() << " " << rec01.GetLength() << endl;
 cout << rec02.GetWidth() << " " << rec02.GetLength() << endl;

 rec02.SetLength(33.44);
 rec02.SetWidth(11.22);

 cout << rec01.GetWidth() << " " << rec01.GetLength() << endl;

 return 0;
}

Next, let’s create a simple class for storing temperatures, called CTemperature. The CTemperature class will hold records on high and low temperature values. We will define a constructor that assigns initial values to the two private data members. The class will have two data access methods, one for retrieving the high temperature value and one for retrieving the low temperature value.

The class specification will go in the file CTemperature.h

#ifndef CTEMPERATURE_H
#define CTEMPERATURE_H

class CTemperature
{

 public:
 CTemperature(double highT, double lowT);
 void UpdateTemp(double temp);
 double GetHighTemp(void) const;
 double GetLowTemp(void) const;
 void PrintTemp(void);
 //private data members
 private:
 double _highTemp, _lowTemp;

};

#endif // CTEMPERATURE_H

Note the use of the const keyword after the methods for retrieving values. We use the const keyword here to tell the compiler that we do not want those data members modified in those methods.

For the implementation, each method in the class will be written outside of the class body using the class scope resolution operator. We will define these methods in a separate file called CTemperature.cpp.

#include "CTemperature.h"

//constructor
CTemperature::CTemperature(double high, double low)
{
 //this-> is optional
 this->_highTemp = high;
 this->_lowTemp = low;
}

//update high or low temp if parameter
//is above or below data members
void CTemperature::UpdateTemp(double temp)
{
 if(temp > this->_highTemp){
 this->_highTemp = temp;
 return;
 }
 if (temp < this->_lowTemp){
 this->_lowTemp = temp;
 return;
 }
}

//return data members
double CTemperature::GetHighTemp(void)const
{
 return this->_highTemp;
}

double CTemperature::GetLowTemp(void) const
{
 return this->_lowTemp;
}

//print values
void CTemperature::PrintTemp(void)
{
 std::cout << "Low: " << this->_lowTemp << " High: " << this->_highTemp << std::endl;
}

We can then try out using this class.

#include <iostream>
#include "CTemperature.h"

using namespace std;

int main()
{
 CTemperature tempObj(80.7, 55.5);

 tempObj.PrintTemp();

 tempObj.UpdateTemp(45.3);

 tempObj.PrintTemp();

 tempObj.UpdateTemp(86.2);

 tempObj.PrintTemp();

 return 0;

}

Objects can be passed as function parameters by value or by reference. How about we create a function to return the range of temperatures between the high temperature and the low temperature. This function will actually copy an object of type CTemperature and use that for calculating the temperature range. Since copying multiple objects can be considered wasteful, we will also create a version of this function that accepts a constant reference to the object, so that in effect only a pointer to the object is copied into the function.

#include <iostream>
#include "CTemperature.h"

using namespace std;

double GetRangeByVal(CTemperature objTemp)
{
 return objTemp.GetHighTemp() - objTemp.GetLowTemp();
}

double GetRangeByRef(const CTemperature& objTemp)
{
 return objTemp.GetHighTemp() - objTemp.GetLowTemp();
}

int main()
{
 CTemperature theTemp(89, 57.4);

 theTemp.PrintTemp();

 cout << "The range in temperatures is " << GetRangeByVal(theTemp) << endl;
 cout << "The range in temperatures is " << GetRangeByRef(theTemp) << endl;

 return 0;
}

That’s enough for today.