One of the most important ideas in OOP is encapsulation. Classes of objects communicate with each other only through public functions that represent class interfaces. Except for these interfaces, each class is a mystery to all other classes. There is no way for one class to reach in and interfere with the internal workings of another. Programmers who design software need know nothing about the internals a class as long as the class's interface does precisely what its designer says it does.
The benefits of encapsulation are very substantial. The system works because each class has a functional spec that states exactly how the class behaves.
In a typical project, a software team constantly rewrites the internals of every part of the program. Without encapsulation, a change to any part of a program can potentially affect every other part.
With C++, a programmer can make any member function or a data member private at the class level. These private members become invisible to the rest of the program; they cannot be accessed.
At the same time, the public members of an object make up its interface. These public members constitute the interface that is visible to the outside world. The program refers to these members, and the assumption by other programmers is that they will not change, so they can build their own logic on top of the existing interfaces. Meanwhile, the programmer of the class can rewrite the internals of the implementation on a need-by-need basis.
The clean division between interface and internals is called encapsulation, which is a fancy name for protecting the insides. C++ approach to encapsulation not only gives a programmer more control over scope but also makes the public/private distinction explicit in the source code of a class. Therefore, the language itself becomes a great aid to documenting which part of a class is its interface and which part is internal.
NOTE: When you're first learning about C++ classes and objects, you may be tempted to use the terms object and class interchangeably. But the distinction is important: a class is a type, and an object is an instance of that type.
One of the ideals of an object-oriented system is that each object be as independent as possible. The system should be able to send a generalized signal to an object and have it respond appropriately. It shouldn't have to know how it carries out the response or even what precise type of the object has been invoked.
The point is that with object oriented approach to programming, we want our main function (or main loop) to know as little as possible. The decisions as to how to carry out a particular task should reside in the objects themselves. The main function is there only to send out a general call when it needs to carry out a task.
In the future, we will show how virtual functions help to accomplish these design objectives. Object-oriented theorists refer to this mechanism as polymorphism, or many forms, from the Greek. I prefer to use uniform interface as a replacement term for polymorhism. The control is delegated to each class responsible for the implementation of each command given by the main function of the program.
This kind of design is a critical part of any graphical user interface (GUI) system, such as Microsoft Windows or UNIX X-Windows. The operating system cannot know ahead of time what all windows might need to do their painting or how they might interact with the user. Otherwise, the application development would be extremely limited. Instead, the GUI-style operating system relies on the individual windows to respond in their own ways to general messages (such as "Initialize your display", etc.)
C++ uses a structured approach for constructing inheritance hierarchies and virtual functions to carry out particular tasks. We shall learn more about both of these terms in our course. In practice, the important thing to know at this point is that the C++ approach is very reliable, convenient, and self-documenting.
OOP features are the most interesting features of C++. C++ user-defined types contain code as well as the data that represent the state of an object at any given time. Compared to C, C++ prevents many programmer's errors through type-safe linkage, which prevents the linker from equating two symbols if they have different C++ type information.
Another concept supported by C++ is overloading, which uses type information to distinguish functions with the same names. Overloading means reusing a name. In C++, one of the most common examples of this is function overloading, which means writing two or more versions of the same function. In reality, overloaded functions are completely distinct and have separate function definitions as well as separate declarations. But from the programmer's perspective, function overloading is a convenient way of providing multiple variations of the same call, but different parameters.
Operator overloading is similar to function overloading, and in fact is a subset of the function overloading. When C++ encounters an operator, it examines the types of the operands to determine how to evaluate them. Implicit in this last statement is the idea that operators can be applied to any type. And this is true: in C++, a programmer can apply addition (plus), subtraction (minus), or any other standard arithmetic operator to a new class. It becomes possible only if the type declaration inside the class actually defines how these operators should work. In other words, you can write a function that defines how the addition operator (plus) works when applied to the user-defined type.
Operator overloading, in effect, enables you to create types that look like true extensions to the C++ language, and once written, they become as fundamental as int (integer) or bool (boolean) types.