Home

The Methods of a Class

 

Member Functions

 

Introduction

The primary motivation of using classes in a program is to create objects as complete as possible. An object must be able to handle its own business so that the other objects of the program or of another program would only need to know which object can take care of a particular need they have.

A regular variable, as a member of an object, cannot handle assignments. This job is handled by particular functions declared as members of a class. A function as a member of a class is also called a Method. On this site, the words “method” and “function”, when associated with a class, will refer to the same thing: a member function of the class.

Declaring Member Functions

A member function, also called a method, is declared like any of the functions we have used so far: it could or could not return a value. Here are two examples:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Rectangle

{

public:

    double Length;

    double Height;



public:

    double Perimeter();

    double Area();

};



int main( int argc, char * argv[])

{

    Rectangle rect = { 48.35, 36.94 };



    cout << "Rectangle Characteristics";

    cout << "\nLength:    " << rect.Length;

    cout << "\nHeight:    " << rect.Height;



    return 0;

}

This would produce:

Rectangle Characteristics

Length:    48.35

Height:    36.94

When using methods on a class, the variables are used to hold or store values, called data, of the object, while member functions are used to perform assignments as related to the class. One way you can control the data held by variables is to hide data from the "external world". To achieve this, you should declare the member variables in a private section. After doing this, use the methods in the public section(s) to help the class interact with the other objects or functions of the program.

There are at least two techniques you can use to implement a method member.

 
 

Method Implementation

 

Local Implementation

To implement a method in the class where it is declared, use the same techniques we used to define regular functions. Here is an example:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



struct Integer

{

    int  Max;

    int  Min;

    int  Size()

    {

        int length;



        length = sizeof(int);

        return length;

    }

    bool IsPositive();

    bool IsNegative();

};



int main( int argc, char * argv[])

{

    Integer number;



    cout << "Size = " << number.Size() << " bytes";

    return 0;

}

When a method is a class' member, it has access to the member variables of the same class. This means that you don't need to pass the variables as arguments: you can just use any of them as if it were supplied. Here is an example:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Rectangle

{

public:

    double Length;

    double Height;



public:

    double Perimeter()

    {

        double p;



        p = (Length + Height) * 2;

        return p;

    }

    double Area();

};



int main( int argc, char * argv[] )

{

    Rectangle rect = { 48.35, 36.94 };



    cout << "Rectangle Characteristics";

    cout << "\nLength:    " << rect.Length;

    cout << "\nHeight:    " << rect.Height;

    cout << "\nPerimeter: " << rect.Perimeter();



    return 0;

}

This would produce:

Rectangle Characteristics

Length:    48.35

Height:    36.94

Perimeter: 170.58
 

Global Implementation

An alternative to local implementation of a method consists of defining it outside of the object. To access a method of a class when implementing it, instead of the member access operator “.”, you will use the scope resolution operator " ::".

To implement a method outside of the class, type the return value of the method, followed by the class' name, followed by the scope resolution operator “::”, followed by the method's name, followed by the arguments, if any, between parentheses, and finally define what the function should do, in its body. Here is an example: 

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Rectangle

{

public:

    double Length;

    double Height;



public:

    double Perimeter()

    {

        double p;



        p = (Length + Height) * 2;

        return p;

    }

    double Area();

};



double Rectangle::Area()

{

    double a = Height * Length;

    return a;

}



int main( int argc, char * argv[] )

{

    Rectangle rect = { 48.35, 36.94 };



    cout << "Rectangle Characteristics";

    cout << "\nLength:    " << rect.Length;

    cout << "\nHeight:    " << rect.Height;

    cout << "\nPerimeter: " << rect.Perimeter();

    cout << "\nArea:      " << rect.Area();



    return 0;

}

This would produce:

Rectangle Characteristics

Length:    48.35

Height:    36.94

Perimeter: 170.58

Area:      1786.05
 

Inline Methods

When studying functions, we learned that an assignment could be carried where it is being called. Such a function was referred to as inline. The same process can apply to a class’ member. 

To declare a class’ method as inline, precede its name with the inline keyword when declaring the method in the class. Here are examples:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Rectangle

{

public:

    double Length;

    double Height;



public:

    double Perimeter()

    {

        double p;



        p = (Length + Height) * 2;

        return p;

    }

    inline double Area();

};



inline double Rectangle::Area()

{

    double a = Height * Length;

    return a;

}



int main( int argc, char * argv[] )

{

    Rectangle rect = { 48.35, 36.94 };



    cout << "Rectangle Characteristics";

    cout << "\nLength:    " << rect.Length;

    cout << "\nHeight:    " << rect.Height;

    cout << "\nPerimeter: " << rect.Perimeter();

    cout << "\nArea:      " << rect.Area();



    return 0;

}

You can choose which method(s) would be inline and which one(s) would not. When implementing the method, you can precede the method with the inline keyword. You can also omit the inline keyword in the class but use it when defining the method. For example, the following code will work just fine:

class Rectangle

{

public:

    double Length;

    double Height;



public:

    double Perimeter()

    {

        double p;



        p = (Length + Height) * 2;

        return p;

    }

    double Area();

};



inline double Rectangle::Area()

{

    double a = Height * Length;

    return a;

}

If you decide to implement a method locally (in the class), you have the option of implementing it as inline. You can precede it with, or omit, the inline keyword:

class Box

{

public:

	inline double CalcVolume()

	{

		return Length * Width * Height;

	}

	double CalcShoeSize()

	{

		return Length - 0.35;

	}

	void Display();



private:

	double Length;

	double Width;

	double Height;

	string Color;

};

On the other hand, if you omit the inline keyword, the C++ compiler would take care of it. Normally, any function implemented in the body of the class is considered inline.

Regardless of how the member methods of an object are implemented, any method can call another without using an access operator. This allows an object’s methods to exchange information among themselves easily. Furthermore, unlike regular functions where a function must be declared prior to another function calling it, the methods of a class don't follow that rule: one method can call another method before or after the other has been implemented, as long as it is defined somewhere in the program. Consider the following Show() method:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Rectangle

{

public:

    void Show()

    {

        Height = 36.94;

        Length = 48.35;



        cout << "Rectangle Characteristics";

        cout << "\nLength:    " << Length;

        cout << "\nHeight:    " << Height;

        cout << "\nPerimeter: " << Perimeter();

        cout << "\nArea:      " << Area();

    }

public:

    double Length;

    double Height;



public:

    double Perimeter()

    {

        double p;



        p = (Length + Height) * 2;

        return p;

    }

    double Area();

};



inline double Rectangle::Area()

{

    double a = Height * Length;

    return a;

}



int main( int argc, char * argv[] )

{

    Rectangle rect;



    rect.Show();

    return 0;

}
 

Static Methods

Besides regular member functions, a class can also have static methods. To create a static method, type the static keyword to its left. Here is an example:

class Car

{

public:

    string   Make;

    string   Model;

    int      Year;

    unsigned NumberOfDoors;

    long     Mileage;

public:

    static int CarsCount;

    static string ApplicationTitle;

    static void Show();

};

As mentioned for static member variables, a static method doesn't belong to a particular instance of the class. This means that you don't need to declare a variable of a class in order to access a static method. A static method stands on its own so much that, if you want to access another member of the class, you must declare an instance of that class inside the static method. In other words, the other members of the same class are not automatically accessible from within the static method. Based on this, the above Show() method could be implemented as follows:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Car

{

public:

    string   Make;

    string   Model;

    int      Year;

    unsigned NumberOfDoors;

    long     Mileage;

public:

    static int CarsCount;

    static string ApplicationTitle;

    static void Show()

    {

        Car vehicle;



        vehicle.Year  = 2004;

        vehicle.Mileage = 24012;

        vehicle.Make  = "Ford";

        vehicle.Model = "Crown Victoria";

        vehicle.NumberOfDoors = 4;



        cout << "\nYear:    " << vehicle.Year;

        cout << "\nMileage: " << vehicle.Mileage;

        cout << "\nMake:    " << vehicle.Make;

        cout << "\nModel:   " << vehicle.Model;

        cout << "\nDoors:   " << vehicle.NumberOfDoors;

    }

};



int Car::CarsCount = 1;

string Car::ApplicationTitle = "  Four-Corner Car Auctions";



int main( int argc, char * argv[] )

{



    cout << Car::ApplicationTitle;

    cout << "\n - Vehicle Characteristics -";

    Car::Show();

    cout << "\nCount:   " << Car::CarsCount << endl;



    return 0;

}

This would produce:

Four-Corner Car Auctions

 - Vehicle Characteristics -

Year:    2004

Mileage: 24012

Make:    Ford

Model:   Crown Victoria

Doors:   4

Count:   1

Notice that, inside of main(), you don't need a Car object (an instance of the Car class) in order to access the Show() method. Also, as mentioned already, you cannot implicitly access the non-static regular members of the class inside of the static method. For example, the following code will not work:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Car

{

public:

    string   Make;

    string   Model;

    int      Year;

    unsigned NumberOfDoors;

    long     Mileage;

public:

    static int CarsCount;

    static string ApplicationTitle;

    static void Show()

    {

        cout << "\nYear:    " << Year;

        cout << "\nMileage: " << Mileage;

        cout << "\nMake:    " << Make;

        cout << "\nModel:   " << Model;

        cout << "\nDoors:   " << NumberOfDoors;

    }

};



int Car::CarsCount = 1;

string Car::ApplicationTitle = "  Four-Corner Car Auctions";



int main( int argc, char * argv[] )

{



    cout << Car::ApplicationTitle;

    cout << "\n - Vehicle Characteristics -";

    Car::Show();

    cout << "\nCount:   " << Car::CarsCount << endl;



    return 0;

}

As done with the other methods, you can implement a static method outside of the class. If you decide to do this, you must omit the static keyword. Here is an example:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Car

{

public:

    string   Make;

    string   Model;

    int      Year;

    unsigned NumberOfDoors;

    long     Mileage;

public:

    static int CarsCount;

    static string ApplicationTitle;

    static void Show();

};



int Car::CarsCount = 1;

string Car::ApplicationTitle = "  Four-Corner Car Auctions";



void Car::Show()

{

    Car vehicle;



    vehicle.Year  = 2004;

    vehicle.Mileage = 24012;

    vehicle.Make  = "Ford";

    vehicle.Model = "Crown Victoria";

    vehicle.NumberOfDoors = 4;



    cout << "\nYear:    " << vehicle.Year;

    cout << "\nMileage: " << vehicle.Mileage;

    cout << "\nMake:    " << vehicle.Make;

    cout << "\nModel:   " << vehicle.Model;

    cout << "\nDoors:   " << vehicle.NumberOfDoors;

}



int main( int argc, char * argv[] )

{



    cout << Car::ApplicationTitle;

    cout << "\n - Vehicle Characteristics -";

    Car::Show();

    cout << "\nCount:   " << Car::CarsCount << endl;



    return 0;

}

To access a static member from a static method, you don't have to qualify it: its name would be enough. Consider the following example:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Car

{

public:

    string   Make;

    string   Model;

    int      Year;

    unsigned NumberOfDoors;

    long     Mileage;

public:

    static int CarsCount;

    static string ApplicationTitle;

    static void Show();

};



int Car::CarsCount = 1;

string Car::ApplicationTitle = "  Four-Corner Car Auctions";



void Car::Show()

{

    Car vehicle;



    vehicle.Year  = 2004;

    vehicle.Mileage = 24012;

    vehicle.Make  = "Ford";

    vehicle.Model = "Crown Victoria";

    vehicle.NumberOfDoors = 4;



    cout << ApplicationTitle;

    cout << "\n - Vehicle Characteristics -";

    cout << "\nYear:    " << vehicle.Year;

    cout << "\nMileage: " << vehicle.Mileage;

    cout << "\nMake:    " << vehicle.Make;

    cout << "\nModel:   " << vehicle.Model;

    cout << "\nDoors:   " << vehicle.NumberOfDoors;

    cout << "\nCount:   " << CarsCount << endl;

}



int main( int argc, char * argv[] )

{

    Car::Show();



    return 0;

}

Notice that the only members that are accessed in the static method without being qualified are the static member variables of the same class.

 

Methods and Arguments 

 

Constant Arguments

In previous lessons, we learned that when a function received an argument that it didn't modify, the argument should be declared as constant. This allows the compiler to make sure that the argument would not be modified. The same technique applies to an argument used by a method of a class.

To declare an argument of an object’s method as constant, type the const keyword on the left of the argument’s data type. Consider a Box object as follows:

We would like to know the area of each side because different things will be displayed on each side and we need to know how much space is available. If we were dealing with a rectangle, we would just declare an area method as follows:

double FaceArea();

On a box (rectangular parallelepiped), we have three rectangle types that represent the six faces. We can declare one method that takes any two sides and calculates their area. Such a method would be declared as follows:

double FaceArea(double side1, double side2);

We can define it as follows:

class Box

{

public:

    double FaceArea(double length, double height)

    {

        double area = length * height;

        return area;

    }

};

Notice that the method doesn't modify the values of the arguments it uses. Therefore, they should be declared as constants. To declare each as constant, you would change the declaration of the method as follows:

double Area(const double side1, const double side2);

Here is an example of a class with methods that take constant arguments:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Box

{

public:

    double FaceArea(double length, double height)

    {

        double area = length * height;

        return area;

    }

    double TopArea(double length, double width)

    {

        return length * width;

    }



    double RightArea(double height, double width)

    {

        return height * width;

    }

};



int main( int argc, char * argv[] )

{

    Box sampleBox;

    const double L = 35.85;

    const double H = 28.46;

    const double W = 22.08;



    cout << " -=- Box Areas -=-";

    cout << "\nTop:   " << sampleBox.TopArea(L, W);

    cout << "\nFace:  " << sampleBox.FaceArea(L, H);

    cout << "\nRight: " << sampleBox.RightArea(H, W);



    return 0;

}

This would produce:

-=- Box Areas -=-

Top:   791.568

Face:  1020.29

Right: 628.397
 

Constant Methods

Some of the methods of an object, though using member variables of the same object, don't modify them. Consider the following program:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Box

{

public:

    double Length;

    double Width;

    double Height;

public:

    double FaceArea()

    {

        return Length * Height;

    }

    double TopArea()

    {

        return Length * Width;

    }



    double RightArea()

    {

        return Height * Width;

    }

};



int main( int argc, char * argv[] )

{

    Box sampleBox;

    sampleBox.Length = 35.85;

    sampleBox.Height = 28.46;

    sampleBox.Width = 22.08;



    cout << " -=- Box Characteristics -=-";

    cout << "\nLength:       " << sampleBox.Length;

    cout << "\nWidth:        " << sampleBox.Width;

    cout << "\nHeight:       " << sampleBox.Height;

    cout << "\nTop Area:   " << sampleBox.TopArea();

    cout << "\nFace Area:  " << sampleBox.FaceArea();

    cout << "\nRight Area: " << sampleBox.RightArea();



    return 0;

}

Notice that the methods that calculate the areas don't modify the values of the member variables they are using. If a method doesn't modify the member variables of its class, the method should be declared and implemented as constant.

To declare a method as a constant, add the const keyword to the right side of the method when declaring and when implementing it. Here are examples:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Box

{

public:

    double Length;

    double Width;

    double Height;

public:

    double FaceArea() const;

    double TopArea() const

    {

        return Length * Width;

    }



    double RightArea() const

    {

        return Height * Width;

    }

};



double Box::FaceArea() const

{

    return Length * Height;

}



int main( int argc, char * argv[] )

{

    Box sampleBox;

    sampleBox.Length = 35.85;

    sampleBox.Height = 28.46;

    sampleBox.Width = 22.08;



    cout << " -=- Box Characteristics -=-";

    cout << "\nLength:     " << sampleBox.Length;

    cout << "\nWidth:      " << sampleBox.Width;

    cout << "\nHeight:     " << sampleBox.Height;

    cout << "\nTop Area:   " << sampleBox.TopArea();

    cout << "\nFace Area:  " << sampleBox.FaceArea();

    cout << "\nRight Area: " << sampleBox.RightArea();



    return 0;

}

If you decide to define constant methods locally (inline), the only difference is to remove the semi-colon of the end of the declaration and define the method normally.

You can also reinforce the constancy of the methods by starting them with the const keyword. The program would still produce the same result.

 

Private Methods

At this time, we know that one of the responsibilities of a member method of an object is to carry assignments. Another job performed by methods is to communicate with the clients of an object. As you might have found out, some of the methods of an object are exclusively used to carry assignments. The external functions or other objects don't call such methods and don't communicate with them. If you create a class and know that a particular method is not used to transfer data to the client methods, you can declare such a method as private, just like you would do with a member variable.

To declare a method as private, include it in the private section of the object. To implement it, follow the same rules we have learned about implementing the methods of an object. The biggest difference you must keep in mind (which will also be very important when we learn about inheritance) is that this function method is not available to the outside world. Here is an example:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

using namespace std;



class Box

{

public:

    double Length;

    double Width;

    double Height;

private:

    const double FaceArea() const;

    const double TopArea() const

    {

        return Length * Width;

    }



    const double RightArea() const

    {

        return Height * Width;

    }



public:

    void Show()

    {

        cout << "\nLength:     " << Length;

        cout << "\nWidth:      " << Width;

        cout << "\nHeight:     " << Height;

        cout << "\nTop Area:   " << TopArea();

        cout << "\nFace Area:  " << FaceArea();

        cout << "\nRight Area: " << RightArea();

    }

};



const double Box::FaceArea() const

{

    return Length * Height;

}



int main( int argc, char * argv[] )

{

    Box sampleBox;

    sampleBox.Length = 35.85;

    sampleBox.Height = 28.46;

    sampleBox.Width = 22.08;



    cout << " -=- Box Characteristics -=-";

    sampleBox.Show();



    return 0;

}
 

C++ Project Files and Classes 

 

Introduction

An object is made of the material that composes it and the actual structure of the object, which defines how the object is built and used. This means that a class is made of two parts: its building block and its definition. These two parts of a class can be kept in different files that have access to each other.

Class' Header File

The building block or foundation of an class is made of the class' creation, listing all of its members. This foundation can be created in a file called a header file, similar to the one we learned when studying functions. The name of the file follows the naming rules we have applied so far. The header file has an extension of .h.

You create an object’s header file the same we did when studying functions. To create the header file, you can just define the class as an object. If some of the members are defined in files outsde of the object, include their header file(s).

Here is what our Box header file would look like:

//---------------------------------------------------------------------------

// Box.h

//---------------------------------------------------------------------------

#if !defined(Box_H)

#define Box_H



class Box

{

public:

    double Length;

    double Width;

    double Height;

private:

    const double FaceArea() const;

    const double TopArea() const;

    const double RightArea() const;



public:

    void Show();

};



#endif // Box_H
 

Class Source Code

The file used to implement the class is called a source file. It can be used to define the assignments of the class. A source file should at least start with a line that specifies the name of the header file that it is implementing. Since this file is usually created in the same project, it is specified with an include line that encloses the file name with double-quotes. An example would be:

#include "Book.h"

The main area of the file is made of the class' implementation. Here is what the source file of our Box would look like:

//---------------------------------------------------------------------------

// Unit1.cpp

//---------------------------------------------------------------------------



#include <iostream>

#include "box.h"



using namespace std;



const double Box::FaceArea() const

{

    return Length * Height;

}



const double Box::TopArea() const

{

    return Length * Width;

}



const double Box::RightArea() const

{

    return Height * Width;

}



void Box::Show()

{

    cout << "\nLength:     " << Length;

    cout << "\nWidth:      " << Width;

    cout << "\nHeight:     " << Height;

    cout << "\nTop Area:   " << TopArea();

    cout << "\nFace Area:  " << FaceArea();

    cout << "\nRight Area: " << RightArea();

}

The main() function of our box project is reduced to simply calling the appropriate Box method member:

#ifdef __BORLANDC__

  #pragma argsused

#endif



#include <iostream>

#include "box.h"



using namespace std;



int main( int argc, char * argv[] )

{

    Box sampleBox;

    sampleBox.Length = 35.85;

    sampleBox.Height = 28.46;

    sampleBox.Width = 22.08;



    cout << " -=- Box Characteristics -=-";

    sampleBox.Show();



    return 0;

}
 
 

Previous Copyright © 2000-2005 FunctionX, Inc. Next