Skip to content

Chapter 5: Classes

CSE 2010: Week 6

What this lecture will cover...

  • So far, we have been using C++ as a procedural language, meaning we have a program that has a bunch of different statements (lines of code) that do something in a specific order.
  • This week we will look at how we can use C++ as an object-oriented language.
  • This lecture will discuss the following:
    • Classes in C++
    • Designing, implementing, and using classes.

Background: Types and Instances

In real life, a type is a concept from which an instance is created. For example, the word circle is a type. We can have different instances of circles, some with different radii.

Background: Attributes and Behaviors

  • Any instance of a type that we encounter has a set of attributes and a set of behaviors.
  • Attributes:
    • An attribute is a characteristic ascribed to an instance.
    • Examples: |Instance Type|Attributes| |-|-| |circle|radius, perimeter, area| |employee|name, address, position, salary| |student|name, year, gpa, grades|
  • Behaviors:
    • A behavior is an operation that an instance can perform on itself.
    • For example, if an instance is an employee, we assume they can give their name, give their address, give their position, etc.

Classes and Objects in Programs

In object oriented programming, we still use terms like type and instances.

Definitions:
  • Class: A USER DEFINED data type that represents a general concept or idea.
  • Object: An instance of a class.

In programming, attributes and behaviors of an object are represented by - Data members: A variable whose value represents an attribute or characteristic of an object. - Member functions: A function that simulates one of the behaviors of an object.

Using Classes in C++

  • Steps to using classes in C++
    1. Design the class.
    2. Define a class by providing the class name , declaring its data members, and declaring its member functions.
    3. Define the class member functions.
    4. Use the class by instantiating/declaring objects of that class type and applying member functions on those objects. For this course, we will show you how to separate your files when using classes.
  • Interface file: will have the class definition (class.h)
  • Implementation file: will have the class member function definitions (class.cpp)
  • Application file: Will have the program that uses the class (.cpp file where your main() function will be).

Step 1: Designing a class

When you are designing a class, think about the following:

  • What idea or concept do you want to represent? (class name)

    • Circle
    • Person
    • Car
  • What “attributes” or “characteristics” do you need to properly represent this type? (class data members)

    • Circle
      • Radius
    • Person
      • Name
      • Age
      • Salary
      • Job
    • Car
      • Make
      • Model
      • Color
      • Year
  • What “behavior” do you want instances of these types to do? (class member functions)

    • Access its attributes
    • Change its attributes

Step 1.2: Deciding on Class Accessibility

Access modifiers determine how a class can be accessed from within or from outside of the class. Going to stick with these for now - Public: - Available to anyone outside/within the class - Private: - Available only within the class - Protected: - Available only within the class and in derived classes (will learn more about this in Chapter 8).

Some rules of thumb: - Make all of your class data members private. You do not want their values to be erroneously accessed or changed. - This is the main idea behind encapsulation. - Your class will have public “setter” and “getter” functions to access/change their private data members. - Make member functions private only if you don’t want the outside world to access them. - They can still be called from fellow class functions.

Step 2: Defining the Class

  • Class definitions are stored in a header file, typically named the same as the class: className.h
  • Within that file you have the following:
//any include statements of other libraries or classes your class might need

#ifndef CLASSNAME_H //These are pre-processor directives, aka header guards.
#define CLASSNAME_H //These are pre-processor directives, aka header guards.
class ClassName
{
    public:
        Default Constructor
        Overload Constructor
        Destructor
        Other member functions (setters, getters, etc)
    private:
        data members
        member functions you want to be private
};

#endif //Used so that the compiler doesn’t get confused about multiple class definitions with the same name.

Step 2: Defining the Class

  • Class definitions are stored in a header file, typically named the same as the class: className.h
  • Within that file you have the following:
//any include statements of other libraries or classes your class might need

#ifndef CLASSNAME_H
#define CLASSNAME_H

class ClassName
{
    public: //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>
        Default Constructor //                               see   >
        Overload Constructor //                             notes  >
        Destructor //                                       below  >
        Other member functions (setters, getters, etc) //vvvvvvvvvv>
    private:
        data members
        member functions you want to be private
};

#endif
  • The “public” section contains member functions, constructors, and destructors that outside functions have access to.
    • Constructors:
      • A member function that creates an object when it is called and initializes the data members of an object.
      • Constructors have the same name as your class.
      • Default constructors have no parameters and they initialize data members to default values.
      • Overload constructors use given parameter values to initialize data members.
    • Destructors:
      • A destructor is automatically called and executed by the system when the object instantiated goes out of scope.
      • The name of the destructor is the same as the class but has a (~) before it.
    • Member Functions:
      • Class member functions that have direct access to data members and other member functions.
      • Setters/Mutator functions are functions that modify an object’s attributes aka change the state of an object.
      • Getters/Accessor functions simply “access” the data of an object, but do not modify it at all.
  • Use the const keyword when defining accessor functions.

Step 2: Defining the Class

  • Class definitions are stored in a header file, typically named the same as the class: className.h
    • Within that file you have the following:
//any include statements of other libraries or classes your class might need

#ifndef CLASSNAME_H
#define CLASSNAME_H

class ClassName
{
    public:
        Default Constructor
        Overload Constructor
        Destructor
        Other member functions (setters, getters, etc)
    private: //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>
        data members //                            see notes below >
        member functions you want to be private //vvvvvvvvvvvvvvvvv>
};

#endif
  • The “private” section is where you place all data members or private functions that will make up our class.
  • Only class member functions have access to these data members and private functions, meaning outside functions cannot directly access them without using a member function.
Example of a Circle class Definition.

Stored in “Circle.h”

/*
 * File name: Circle.h
 * Header file containing the Circle class interface/definition
 * This interface:
 *    - Defines the class
 *    - Declares the class data members
 *    - Declares the class member functions
 */
#ifndef CIRCLE_H
#define CIRCLE_H

class Circle
{
    private:
        double radius; //attribute representing the radius
    public:
        Circle(); //default constructor
        Circle(double r); //overload constructor
        ~Circle(); //destructor
        void setRadius(double Radius); //mutator
        double getRadius() const; //accessor
        double getArea() const; //accessor
        double getPerimeter() const; //accessor
};
#endif 

Step 3: Defining Class Member Functions

  • Ok, so we have our class defined, but now we need to actually write the code for the member functions.
  • At the top of the implementation file, you MUST have the following:
    • #include “className.h”
  • Then define all the functions using the following format:
    • return_type className::functionName() { }
  • Define every single function, constructor, and destructor that you’ve declared.
  • All class member functions have direct access to the private data members, so this means that they can use parameter values, data members, and any new variables they declare in order to complete their task.

Example of Circle class member function definitions

Defining the constructors and destructors.

Note that constructors have the special ability of using an initialization list to define data member values.

class Circle
{
    private:
        double radius; //attribute representing the radius
    public:
        Circle(); //default constructor
        Circle(double r); //overload constructor
        ~Circle(); //destructor
}
/*
 * File name Circle.cpp
 * Implementation file containing the Circle class member function definition
 */
#include "Circle.h" //include interface file
#include <iostream>
#include <cmath>
using namespace std;

//Default constructor that just sets radius to a default value
Circle::Circle():radius(0.0){
    cout << "The default constructor was called.\n";
}

//overload constructor that sets radius to provided value
Circle::Circle(double r):radius(r){
    cout << "The overload constructor was called.\n";
}

//the desctructor that is called when the objects no longer exist
Circle::~Circle(){
    cout << "The destructor was called for circle with radius: " << radius << "\n";
}

Example of Circle class member function definitions

Defining the rest of the functions

        void setRadius(double radius); //mutator
        double getRadius() const; //accessor
        double getArea() const; //accessor
        double getPerimeter() const; //accessor

};
#endif
// set radius for the circle
void Circle::setRadius(double radius){
    // this->radius will refer to the data member radius
    // radius will refer to the parameter radius
    this->radius = radius;
}
// return the value of the private data member
double Circle::getRadius() const{
    return radius;
}
// return the area of the circle
double Circle::getArea() const{
    return M_PI*radius*radius;
}
//return the perimeter of the circle
double Circle::getPerimeter() const{
    return 2*M_PI*radius;
}

Step 4: Using your class by declaring OBJECTS

  • Once you have defined your class and all of its member functions, you can finally use your class!
  • Use a class by declaring objects.
  • Need: #include “className.h”
  • To declare a new object, can use either default or overload constructor:
    • className objectName; //will use default constructor
    • className objectName(arguments); //will use overload constructor

Once you’ve declared an object, you can use it to invoke/call member functions objectName.functionName(arguments);

Example program that uses the Circle class

/*
 * File name Circle.cpp
 * Application file that uses the Circle class
 */
#include "Circle.h"
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    //declare a Circle object using the default constructor
    Circle circ1;
    cout << "circ1 radius: " << circ1.getRadius() << "\n";
    double radius;
    cout < "Enter a radius: ";
    cin >> radius;
    //setting a new radius
    circ1.setRadius(radius);
    cout << "circ1 new radius: " << circ1.getRadius() << "\n\n";

    //declaring a Circle object with overload constructor
    Circle circ2(5.2);
    cout << "circ2 radius: " << circ2.getRadius() << "\n";
    cout << "circ2 area: " << circ2.getArea() << "\n";
    cout << "circ2 perimeter: " << circ2.getPerimeter() << "\n\n";

    //declaring a Circle object with overload constructor
    Circle circ3(2.5);
    cout << "circ3 radius: " << cir3.getRadius() << "\n";
    cout << "Enter a radius: ";
    cin >> radius;
    //setting a new radius
    circ3.setRadius(radius);
    cout << "circ3 new radius: " << circ3.getRadius(); << "\n\n";

    //calls to destructors happen here without us calling them
    return 0;
}

Compiling all of our separate files

  • At this point we have the following 3 files:
    • Circle.h //definition of Circle class
    • Circle.cpp //member function definitions
    • Circle_main.cpp //program that uses Circle class
  • We can compile all files together using a makefile
  • In the makefile, we list all of our target files/executables, and the commands we would use to create them.
  • Steps to create a makefile for the Person class:
  • vi makefile
  • Type every pair of lines that has the following format:

target: source(s)

rule/command

  1. Now to compile and link the program, simply type

make