C++ Class Construct  «Prev  Next»
Lesson 6 Overloading member functions
Objective Overload member functions in the same class.

Overloading Member Functions in C++

C++ enables several functions of the same name to be defined, as long as they have different signatures. This is called function overloading. The C++ compiler selects the proper function to call by examining the number, types and order of the arguments in the call. Function overloading is used to create several functions of the same name that perform similar tasks, but on different data types. For example, many functions in the math library are overloaded for different numeric types the C++ standard requires float, double and long double overloaded versions of the math library functions.
  • Procedural Overloading of Function:
    Figure 3-6 uses overloaded square functions to calculate the square of an int and the square of a double. C++ treats whole number literal values as type int. Similarly, line 24 invokes the double version of function square by passing the literal value 7.5, which C++ treats as a double value. In each case the compiler chooses the proper function to call, based on the type of the argument. The last two lines of the output window confirm that the proper function was called in each case.
    Figure 3-6
    #include <iostream>
    using namespace std;
    
     // function square for int values
     int square(int x ){
      cout << "square of integer "  << x << " is ";
      return x * x;
     } 
    
     // function square for double values
     double square(double y ){
      cout << "square of double " << y << " is ";
      return y * y;
     } 
     // ----- main
     int main(){
      cout << ; // calls int version
      cout << endl;
      cout << ; // calls double version
      cout << endl;
     }
    
    Output of program below:
    square of integer 7 is 49
    square of double 7.5 is 56.25
    

Overloading Functions within Class

Member functions within the same class can be overloaded. Remember that a function is called based on its signature, which is the list of argument types in its parameter list. Consider adding to the class ch_stack a pop operation which has an integer parameter that is the number of times the ch_stack should be popped. It could be added as the following function prototype within the class:
class ch_stack {
   .....
   char pop(int n);      //within ch_stack
   .....
};

char ch_stack::pop(int n)
{
   assert(n <= top);
   while(n-- > 1)
     top--;
   return s[top--];
}

The definition that is invoked depends on the actual arguments to pop:
data.pop();           //invokes standard pop
data.pop(5);          //invokes iterated pop

The C++ Programming Language

C++ Objects and Member Functions

A member function is conceptually part of the type. There is no distinct member function pop for each ch_stack object. The declaration
ch_stack s, t, u;

creates three separate ch_stack objects of sizeof(ch_stack) bytes. Each of these objects has its own data members:

char  s[max_len];
int   top;

A member function is conceptually part of the type.
There is no distinct member function for any of these three ch_stack objects.
NOTE: To follow the const-correctness principle, it is always a good idea to declare member functions that do not change any data member of the object as being const. These member functions are also called inspectors, compared to mutators for non-const member functions.

Employee.cpp

This section discusses the implementations for the Employee member functions. The Employee constructor sets the initial values for the Employee's data members. By default, new employees have no name, an employee number of -1, the default starting salary, and a status of not hired. This constructor implementation shows a second mechanism to initialize class member variables. You can either put the initialization between the curly braces in the body of the constructor, or you can use a constructor initializer, which follows a colon after the constructor name.
#include <iostream>
#include "Employee.h"
using namespace std;
namespace Records {
Employee::Employee()
: mFirstName("")
, mLastName("")
, mEmployeeNumber(-1)
, mSalary(kDefaultStartingSalary)
, mHired(false)
{
}
The promote() and demote() methods simply call the setSalary() method with a new value. Note that the default values for the integer parameters do not appear in the source file; they are only allowed in a function declaration, not in a definition.
void Employee::promote(int raiseAmount){
 setSalary(getSalary() + raiseAmount);
}
void Employee::demote(int demeritAmount){
 setSalary(getSalary() - demeritAmount);
}

The hire() and fire() methods just set the mHired data member appropriately.
void Employee::hire(){
mHired = true;
}
void Employee::fire(){
mHired = false;
}

The display() method uses the console output stream to display information about the current employee. Because this code is part of the Employee class, it could access data members, such as mSalary, directly instead of using getSalary(). However, it is considered good style to make use of getters and setters when they exist, even within the class.
void Employee::display() const
{
cout << "Employee: " <<  getLastName() <<  ", " <<  getFirstName() <<  endl;
cout <<  "-------------------------" <<  endl;
cout <<  (mHired ? "Current Employee" : "Former Employee") <<  endl;
cout <<  "Employee Number: " <<  getEmployeeNumber() <<  endl;
cout <<  "Salary: $" <<  getSalary() <<  endl;

cout <<  endl;
}


There is quite a bit more to overloading functions, but this requires a more in-depth look at polymorphism, which is covered in the third course in the C++ for C Programmers series, Designing Reusable Code in C++.

SEMrush Software