Skip to Content

C++: Intro to Object-Oriented Programming (OOP) Ideas

What is Object-Oriented?

Object Orientation is the combination of three main ideas:

  • Encapsulation: this means putting things together to make it look like a whole and to hide the internal things from external inspectors outside.
  • Inheritance: this means that some types can be subtypes of other things and inherit their features. For this, always think of the phrase “is-a”. For example, a bear is-a mammal. Bears inherit features of mammals (all mammals have hair; bears have hair).
  • Polymorphism: this means that things in your program can act differently based on the context. (Greek “poly” means many, “morph” means form; so the word means “many forms”)

It will take us most of the rest of the semester to introduce these three concepts.

Every “object-oriented” language has these three capabilities. If a language does not, it should not claim to be an OO language.

What is Good Object Oriented Programming?

When we get to a programming language, most OO programming languages use the keyword class – and we quickly start thinking about what classes our program should have.

This is bad! Object oriented programming is about objects!

When we are writing code, we are looking at a description of a computation that will happen when our program executes. Because objects exist at runtime, we sometimes forget about them when looking at our code, and only think about classes. This is bad!

A class simply is a description of a particular kind of object (but we might create many objects of that kind). Because of this, a class name should always be singular. It is a name of a kind of object; e.g., Customer is a good class name. Customers is not a good class name; if you need to keep track of a collection of customers, then you should call your class SetOfCustomers (set is singular), or better yet use a generic/template such as Set<Customer>.

What is an Object?

Think of an object as a living thing. In an executing program, objects do have a lifetime: they are created, they do things, and then they are destroyed. Living things can do things, they have capabilities; living things also have characteristics, they have attributes. To read more about this concept, see here and here.

In programming, the attributes of an object are the data members in the object. Data members must always be private; only the object itself should be allowed to modify its own attributes. This is the reason that setter methods are evil; they are just a way to allow the outside world to modify attributes. Getter methods are also somewhat evil; usually they indicate lazy programming and misplaced capability. If something needs done using an object’s attributes, the object itself should do it! To read about getters and setters being evil, look here, here, and here. Unfortunately many “OOP” textbooks immediately tell students to create getter and setter methods. Rip those pages out of your textbook!

The capabilities of an object are the methods (or operations) of the object; Public methods are the interface that the object presents to the rest of the world; these are things that the object can do to or for the rest of the program. Private methods are generally helper methods that are used to help better organize our code (divide-and-conquer) so that the public methods are cleaner.

So what is a Class?

OO programming languages use the class idea to allow a programmer to create a new datatype, which is “this kind of object”. Just like a built-in type, such as int, once a class is defined, you can create variables that hold the kind of object that you defined with the class.

An object is an instance of a class. Just like each integer variable is an instance of the type int, each object is an instance of the user-defined data type (the class). It’s no different!

Always be thinking of a single object when writing the code for a class, even if you will create many objects of the class. E.g., when creating a Customer class, you are describing what one Customer object is and can do, even if you will create many of them.

Encapsulation: The First Object Oriented Concept

In OO languages, encapsulation takes on two forms:

One: Functions (now called methods, or member functions) that are associated with the data of the object are placed, in your code, inside the class. So both data and computation are encapsulated into the object (in your code, the class). The non-OO C language has structs, which only allows data fields in it. The OO idea of a class adds in functions (now called methods).

Two: new access modifier keywords public and private allow you to explicitly state which elements of an object are visible from the outside (public) and which are hidden (private). Once we bring in inheritance, even more access modifiers like protected are used. It is because methods are part of, and inside, the object that we can have private elements; the method code that uses them is inside the object. When programming it is easy to think that private means usable inside the class, but in reality in means usable inside the object.

Encapsulation, with the use of private, enables what is known as information hiding, the idea that some part of your program hides its details from the rest of the program. Information hiding has long been a very fundamental program design goal. In OOP programming, it is done based on objects and classes, using encapsulation.

Non-OOP programming languages, like plain C, do have the ability to create data aggregates, often called records or tuples or structures, but these do not have functions in them, nor is anything private. In plain C, the struct keyword lets you declare data records.

C++ allows the keyword struct to still be used, even with methods, but it has members that are by default public. In a C++ class, members are by default private. However, it is generally good practice to explicitly declare which members are public and which are private anyway.

Inheritance and Polymorphism

See these other pages: Inheritance and Polymorphism.

Constructors and Destructors

Because object data (class data members) is private, when an object is created, the object itself needs to initialize its data (since no other code can access it). OOP languages use constructors for this. Constructors are methods that are the same name as the class (in most OOP languages); they automatically get called when an object is created. Most languages allow you to have multiple constructors that take different arguments, and the correct one is used based on how you chose to create the object. A constructor method that takes no arguments is known as the default constructor.

C++ is an OOP language that requires you to explicitly delete or destroy objects (although modern versions have smart pointers that help with this). In C++, since you know exactly when an object is being destroyed, you can write a destructor method in the class that cleans up whatever resources the object might be holding, including perhaps destroying other objects that this object is holding references to. Only one destructor method is allowed.

Java does not allow a programmer to destroy an object, but rather it uses garbage collection to clean up objects that are no longer being used. When this happens is unknown to the programmer, so Java does not have destructors. However, Java does allow a finalize() method that can work similarly, but there is no guarantee that it will ever be called.

When programming C++ the mechanics of the language cause more “constructing” than you might think. There are special cases where copy constructors and move constructors and specialized assignment operators are needed.

Example C++ Class

class Line
{
   public:
      // constructors (overloaded)
      Line();
      Line(int x1, int y1, int x2, int y2, int color=0);
      ~Line(); // destructor
      // public methods
      void movePosition(int x1, int y1, int x2, int y2);
      void reColor(int color);
      void translateTo(int x, int y);
      double length(void);
      void draw(void);
   private: // private data
      int x1;
      int y1;
      int x2;
      int y2;
      int color;
};