In this article I am sharing the basic concepts of Object Oriented Programming (OOP): Objects and Classes, Inheritance and Polymorphism. This article will also discuss the need of OOPs. After this we will see the importance of OOPs over Structured programming. In last we will also discuss the brief history of C and C++ languages and the relationship between C and C++.
Why We Need OOPs
Before I write about Object Oriented Programming (OOP), let us understand the limitations of procedural programming, modular programming, structured programming etc.
In earlier days, the programs were written in machine languages that were loaded into memory through a set of console switches or through a numeric keypad. Such programs were very difficult to debug. After this assembly language was designed that enabled us to use mnemonic codes for machine instruction and symbolic names for memory locations. But still our machine understood only the machine language. Therefore assemblers were needed to translate assembly language programs into machine codes. Since the concept of assembly language was still machine independent and it was very difficult to debug large and complex programs.
After that high level language such as FORTRAN, BASIC and so on are designed. These higher level languages are just like English language. The programs written in higher level languages are translated into machine language by a compiler. Each higher level language has its own compiler. The programming in higher level language is simpler than low level language. But still these programs have some following limitations:
1. The program, which was used once, can not be reused.
2. The programs used global variables. And it was very difficult to trace out the changes in these global variables.
3. It was very horrible to write, understand and maintain complex programs.
These limitations are overcome by procedural languages that also support structured programming. In this the large programs are broken into smaller units. For this reason, the functions/ subprograms/ procedures are introduced in these higher level languages to make programs more comprehensible to their human creators. Thus a large program is divided in various functions and each function performs a well-defined task. Each function is also clear defined interface to the other functions in the program. Each function has its own local variables and set of instructions to perform a well-defined task.
• The idea of breaking a program into functions can be further extended by combining a number of functions into a large entity called a module. The concept is same even for a module – a module is made to carry out specific task. Therefore structured programming concept involves both dividing a program into functions and modules, one of the corner stones of structured programming.
• Structured programming also introduced a new concept – abstraction. In structured programming, programmer needs to know only the task performed by functions, rather than to know how that task is performed by that function. This is called functional abstraction. And it is another corner stone of structured programming.
• But the structured programming begins to loose its grip over programmers, as programs grow ever larger and more complex. One of the most crucial reasons for the failure of procedural language is the role played by data.
• In a procedural language, the whole emphasis on doing things – read the data, check for errors and finally display the data, if there is no error. Therefore the concept is how to receive the data, how to process the data, how to display the data and so on. The functions that perform these activities are given prime status in the organization of procedural languages and the data is given second class status in the organization of procedural languages whereas data is, after all, the reason for a program’s existence.
• Thus procedural-programming concept is to decide which functions/procedures you want and then select the best one that suited your requirement.
• In procedural languages, the programs use both global and local variables. If data is treated as global, then they are accessible to all functions or programs. It means that one function may read it, one may analyze it, one may update it, and one may display it and so on. Therefore knowingly or unknowingly any function can corrupt this global data. On the other hand, if the data is defined as local then they are not accessed by many different functions, because local variables are accessed within the function.
• Another reasons with structured programming is that their major components – functions and data structures do not model the real world very well. For example, let you are writing a program to create the elements of Graphic User Interface (GUI): menus, windows and so on. One can not predict – what functions will you need? What data structures you need? Thus there are no obvious program elements to which a menu or a window would correspond because procedural languages fit a problem to the procedural approach that is they fit the problem into the functions.
• Another problem with procedural languages is that of creating a new data types. Built – in data types, such as integers, real numbers, and characters are provided by the language. On the other hand if programmer wants to create its own data type, such as data type that deals with complex numbers, then for traditional languages it is very difficult to create such data types.
Therefore more programmers are started to use Object-Oriented Programming (OOP). The OOP languages provide a new way of organizing data and code that promises increased control over the complexity of the software development process.
Object Oriented Programming
• The basic idea behind Object Oriented Languages is to combine into a single unit both data and functions that operate on this data. Such a unit is called an object. An object represents an entity that can store data and has its interface through functions. The data of an object are called as data members and the functions are called as member functions in C++. The member functions are also referred as methods in some object–oriented languages such as Smalltalk. These data members represent the information contained in the object and member functions define the operations that can be performed on that object.
• While accessing this data, one can not access it directly. The only way to access its data is through its member functions. It means that if we want to read a data item, we call a member function in the object. This function reads the item and returns the value to us. Therefore the data is hidden for the functions that are defined outside the object. This is known as data hiding. And obviously it is safe from accidental alteration.
• The data and functions are said to be encapsulated into a single entity. Thus the data encapsulation and data hiding are the main pillars of Object Oriented Programming (OOP).
• It is the data abstraction that specifies the data as well as the functions to be used by others. You can also say that data abstraction is the process of defining a new data type, together with the principle of data type. In C++, class is synonymous with a data abstraction. Thus a class represents a template from which objects are created and when an object is created it sets aside a memory space for the data members of the objects.
• A C++ program typically consists of a number of objects, which communicate with each other by calling one another’s member functions.
When we solve a problem in an Object Oriented Programming environment, we divide the problem into objects rather into functions. However when you will see a C++ program first time, you see that most individual programming statements in C++ are similar to statements in C. Even member functions in C++ look alike a procedural function in C. When you look at the complete large program only then you can determine whether it is a part of a procedural language or an Object Oriented C++ program.
Characteristics of OOP
The major components of Object Oriented language in general and C++ in particular that overcomes the limitations of procedural languages are as:
1. Objects
2. Classes
3. Inheritance
4. Reusability
5. Polymorphism
6. Dynamic Binding
7. Message Communication
Objects
In a procedural programming approach we divide our problems into functions. But in Object Oriented programming it will be divided into objects. And it is easier way to design a program in terms of objects rather than in functions. But now the question arises – what kinds of things becomes objects in Object Oriented programming. Actually there is no hard and fast rule that specifies that it must be treated as objects and it must not. It is the programmer who selects the objects according to his limitations. Here are some typical candidates that can be treated as objects in different programming environment:
• Students in a library management system
• Programming constructs such as array, stack, queue, linked list etc.
• Graphics user interface elements such as windows, menus, graphic objects (icons) mouse and keyboard.
• Elements in computer games such as chess, cannons, guns, animals etc.
• User defined data types such as distances, complex numbers etc.
Classes
A class is a specification of describing a user-defined data type and an object in C++ is an instance of a class or you can say objects are members of classes. We know that almost all computer languages have built–in data types, such as int, floats and chars. If we want to declare x, y, and z of type integer then we use following statement
int x, y, z;
Like this once a class has been defined, we can create any number of objects belonging to that same class. Thus a class is an entity that specifies what data and functions will be included in object of this class. Just as the mere existence of a type int does not create any integer variable, likewise when a class is defined it does not create any object; it just defines a new data form.
Inheritance
OOP provides a concept of inheritance. Unlike built–in data types, one class can inherits the properties of another class by using inheritance. Inheritance is the capability of a new class to inherit the data and functions of the old class without knowing the details of old class. The new class is known as derived class and the old class is known as base class. The derived class not only inherits some characteristics from its base class but also adds some new features of its own.
The set of base class and derived class instances is referred as the class inheritance hierarchy. Multiple inheritance is one of the many types of inheritance. By multiple inheritance we mean deriving a class from more than one base class. Not all Object-Oriented Programming languages support multiple inheritance.
Reusability
One of the main objectives of OOP is of its reusability. Once a class has been written, created and tested, it can be distributed to other programmers for use it in their own programs. This functionality is called as reusability. If these programmers want to add their own new features then new classes can be derived from it. This new class will inherit the capabilities of the old one but is free to add new features of its own.
For example, let we have a class that adds and subtracts two complex numbers. So here if we derive a new class from this class then the new class contains both these, addition and subtraction, features and can add its own feature of multiplying two complex numbers and so on.
The ides of inheriting a class can be further extended by creating a derived class from another derived class. It means that if we have derived a class–B from a base class–A then class–C can be derived from class–B . Here the class–C naturally inherits the properties of class–A and this property of inheritance is known as transitive nature of inheritance.
Polymorphism
In a general term, polymorphism means the ability of having more than one form. In the context of OOP, polymorphism is the ability for a data to be processed in more than one form or you can say that different objects react in different manner to the same operation. We know that the arithmetic operator + (plus) is generally applied on built–in data types, such as integers, floats etc. For example, we can use the expression (a+b) to denote the sum of a nad b, for so many values of a and b. And if we want to apply + (plus) operator on user defined data type then we will define new operations for this + (plus) operator. For example we can even define the ‘+’ operator for two strings to mean the concatenation of the string.
Let we have two strings:
char name1[20] = “ATI”;
char name2[10] = “SHRESTHA”;
If we want to concatenate these two strings then we will use the following statement:
strcat(name1, name2);
And by using polymorphism property we can write it as:
name1 = name1 + name2 ;
This + (plus) operator will be the member function of say string class. Like this other operators can also be operated on user defined data types. This is called as operator overloading. Like this we can also have a single function name to handle different numbers and types.
This concept of using a single function name to perform different type of activities is known as function overloading. Thus using operators and functions in different ways, depending upon what they are operating on, is called polymorphism.
Dynamic Binding
Generally binding is performed either at compile time or at run time. The binding which is done at compile time is known as static binding (early binding) and the binding which is done at run time is known as dynamic binding (late binding). Thus we can determine only at run time that which function is called. Basically dynamic binding is associated with polymorphism and inheritance.
Message Communication
Another important feature of OOP is message communication that is idea of sending message to an object, causing it to perform an operation by invoking the appropriate function of the object. And of course the calling member function of the object must be capable of handling the operation you want. This is a typical message communication between two objects.
Importance of OOPs over Structured Programming
• OOPs provide the concept of object and class to encapsulate the data and functions into one entity. Structured programming does not support such facility.
• OOPs provide the concept of data hiding that helps programmers to have secured data from improper access.
In OOPs, data are treated as first class entity, whereas structured programming treats functions as first class entity and data as second class entity.
• OOPs provide the facility of having multiple instances of an object to coexist with any interference.
• OOPs provide the facility of inheritance in which we can derive a new class from an older one. On the other hand, structured programming does not support such facility.
• OOPs also provide the facility of reusability of the existing class without modifying it.
• In OOPS, we can use same function name for two or more functions. On the other hand, in structured programming we use unique name for each function.
• OOPs also provide the additional meaning to arithmetical and logical operators. It means that we can perform arithmetical and logical operations on user defined data type also. In contrast to this, structured programming performs these operators on built – in data type only.
Advantages of OOP
It is easy to write simple programs for small problems. But the situation becomes complex when the program size becomes large. Therefore while writing complex programs there may have some error, either at logical level or at any run time level. And it is the Object Oriented Paradigm that provides some new and powerful features to solve this complexity. The objectives of Object Oriented Programming are clearer, more reliable, more easily maintained programs. The Object Oriented Paradigm is the latest invention in the software development. Thus the ultimate conclusion is that sooner or later the Object Oriented approach to organize a program impresses every computer programmer.
OOPs and C++
C++ is one of the most popular languages that support OOPs features. C++ joins together two separate programming traditions – procedure oriented programming, represented by C, and object oriented programming, represented by C++, a superset of C language. The main reason to avail you of its object oriented features. Since C++ is a superset of C language, so for the C programmers it would be a bit easy to migrate from Turbo C to Turbo C++. Now one may ask – Is it necessary to have sound background in Standard C? Its answer is Yes and No. Knowledge of C would certainly help in understanding loops, arrays, structures, and pointers of C++. But if you do know C then the transformation of C lovers from Turbo C to Turbo C++ is very exciting and thrilling.
Actually C and C++ are two different languages, though they have similar syntax. C++ is a fresh programming methodology designed to cope with escalating complexity of modern programming tasks. We can also say that C++ is the language of future.
History of C
• C was developed by Dennis Ritchie a programmer at AT and T Bell laboratories, in the early 1970s. It was not his motto to design a new language at that time. Actually he was working on a project to develop the Unix multi-user, multitasking operating system along with another programmer Ken Thompson. Initially Unix was written by Ken Thompson in machine language. But due to lack of portability Unix was restricted to use on the specific machine, say PDP-7 and PDP-11.To overcome this limitation, they needed a language that was concise, that produced compact, fast programs, and that could control hardware efficiently. This necessity invented the development of another new high level language C; thus C was intentionally design to make Unix portable.
• After the development of C, Ken Thompson successfully rewrote Unix in C and no doubt they made programming history. Now almost 90% Unix was written in C and thus it was made a truly portable operating system. Another main point to note that Unix was the first major operating system to be written in something other then low-level programming language. Since Unix was not 100% portable, so when Unix is ported to another type of system it needed rewriting a few assembly language operating system drivers and interface functions, and recompiling the operating system. This feature made C as a unique language that could be used to write system programs and that could be used to write portable programs, a goal that was never achieved by the high level language that came before it.
• The C++ language has been available outside AT and T since about 1985. Now a day C++ like C before it, has become the language of choice among programmers.
History of C++
• C++ programming language was designed and developed by Bjarne Stroustrup also at AT and T BELL laboratories in the early 1980’s as a means of making programs easier to write and maintain. At that time people found that there are some limitations in procedural languages like Pascal, Basic, Fortran, Cobol etc. The limitations of procedural language are already discussed in earlier section.
• Therefore rather than design a new language from the ground up, Bjarne Stroustrup decided to build upon the C language. Bjarne Stroustrup added some new features, such as objects, classes, polymorphism, inheritance, operator overloading, functions overloading etc, to the most popular language C without significantly changing its components. Some features were taken from one of the earlier object oriented language: Simula67. Bjarne Stroustrup called it “C with classes” originally. Later it was named as C++ (pronounced as C plus plus) where “++” is the C increment operator indicating an incremental development of C. Thus C++ is a superset of C, meaning that any valid C programming is a C++ programming too.
• The other languages that support OOPs features are Smalltalk, Simula, Objective C, Eiffel, Turbo Pascal 7.0, Java etc. Among these OOPs languages, C++ is by far the most popular languages and Java is the latest one.
• C lovers might wonder about C’s future given the current popularity of C++ and object-oriented programming. Some C++ lovers might say that C++ would the language of choice. To some extend, it is true but C is more suitable for solving some special programming problems. Many C++ lovers might not agree with this opinion, but it is widely held by others. You might be surprised to know that window 98 operating system is written almost entirely in C, even though its developer, Microsoft, also developed Visual C++. However of course, if one were to understand the development from scratch of a new operating system today, the language of choice probably would be C++.
C versus C++
Now let us see some distinguish features of C programs and C++ programs. Since C++ is a superset of C, it means that a C++ compiler is able to compile any C program. However there are suitable differences between C programs and C++ programs.
The C++ language has some extra reserved words that are not reserved by the C language. Such extra keywords can be used in a C programs as identifier for functions and variables C programmers can omit function prototypes, as they are optional in C program. But it is compulsory to declare function prototypes in C++ programs.
Many standard C functions have counter parts in C++, and C++ programmers view them as improvements to the C language. Here are some ones:
• The C++ provides new and delete dynamic memory allocation/deallocation operator that replace standard C’s malloc() and free() functions.
• The C++ iostream class library replaces Standard C’s stdio function library for console input and output.
• The C++ provides try\catch\throw exception handling mechanism that replaces standard C’s setjmp() and longjmp() function.
Structure of a C++ Program
Actually C++ is a procedural language with the object-oriented extensions. It means that we can define as well as instantiate (create from a class) objects in C++. The procedural modules in C++ programs are called functions. Every C++ program consists of one or more functions. Any function can call any function. Even a function can call itself.
Functions may contain parameters. When a function is called, the values for its parameters are passed to the called function. Some functions return a value and others do not. The calling function that returns a value can code the function call on the right hand side of an assignment statement, assigning the returned value to a named variable. Each function consists of one or more block statements. In C++ a block is just a set of statements enclosed in a pair of curly braces ‘{’ and ‘}’. Each block has its own set of local variables, which remains in scope as long as the statements in that block are executed. A C++ program can also have global variables. Global variables are declared outside all functions. Global variables are called as global because the statements in all functions in the same source file can reference them.
In C++ statements are one of the following types:
• Declaration Statements – The statements that declare variables and functions are called as declaration statements. A variable declaration specifies the variable’s storage class, data’s type, name and dimensions, if it is an array. A function declaration, also known as function prototype, declares the function’s return type, name and number and types of its arguments.
• Definition Statements – The statements that define the instances of variables and functions are called as definition statements. A variable definition includes the components of declaration and may include an initializer if the variable has an initializing value. A function definition contains the function’s executable code.
Here one should remember that a variable declaration and definition are the same statement but a function declaration and definition are usually in different places. However the function definition may also serve as its prototype only if the function’s definition appears in the source code file ahead of all calls to the function.
• Procedural Statements – These statements include assignments, expressions, or control statements. Expressions consist of variables, constants, operators, and function calls. An expression can stand on its own or be on the right side of an assignment statement.
I have already written that in this article that a function is collection of statements which is designed to perform a specific task. The statements must appear in the function in the same order in which we wish them to be executed. C provides sequential, selective and repetitive statements. C++ allows separately compiled functions to used without being in the program proper, that is a function can be accessed by any program.
Here is the structure of a typical C++ program:
[Preprocessor Directives]
[External Variable Declaration]
[Class Definition and Declaration]
main()
{
[Local Variable Declaration]
Program Statements
}
[User-defined Functions] The square brackets denote optional structures.
A Simple ‘C++’ Program
Before going into the depth of C++, let us consider a very simple program, examine it and try to discover what it does.
Program article1.cpp represents a very simple C++ program.
/ Program – article.cpp // Comment statement
#include // Preprocessor directive
void main() // A function heading
{
cout << “Nobody is greater than God.”; // Statement
}
Like C, every C++ program is basically a collection of functions in which main () is an essential function and several other fundamentals. C++ language constructs. Typically, we organize a program into major tasks, then design separate functions to carry out these tasks.
The main () function
Almost every C++ program consists of one or more functions in which main() is an essential function. It provides the entry and exit points to the program. The program starts executing with the first statement in main() and terminates when the main() function returns.
The program article1.cpp consists of a single function main(). The very first line of the function, main(), is called the function heading, and the portion enclosed in the braces ({ and }) is called the function body. The single left brace ‘{‘ character defines the start of main()’s outermost statement block. The statement block continues until its corresponding enclosing right brace ‘}’ character encounters. A brace surrounded group of statements is called a statement block.
Every function has at least one statement block. The statement blocks can be nested. It is the function heading that interfaces between the rest of the program and the function. The function body represents the activity performed by the function. The program article1.cpp has the following statement block:
{
cout << “Nobody is greater than God”; // statement
}
this statement block has only one statement:
cout << “Nobody is greater than God”;
This statement tells the compiler to display a string constant on the screen. Like C, in C++ every statement is ended by a semicolon (;). If you do not mention a semicolon then the compiler will definitely signal an error message.
Generally, a C++ function is called by another function. The part that precedes the function name is called the function return type, and it describes the information flow from the function to the function that called it. The part that follows the function name is called the argument list, and it describes the information flow from the calling function to the function being called. In the program article1.cpp, the word void preceding the function name describes that this particular function does not have a return value. Since main() takes no argument so the argument list is empty.
In short void main(void) states that the main() function does not return any value to the function that calls it and that main() function takes no argument from the function that calls it. If a function is not receiving any argument then it is optional to have void in the argument list. Thus the following notations are treated similarly by the C++ compiler:
void main(void) or void main()
Now the question arises – why the main() function is an essential function? (And not, by the way, MAIN() or Main() or mane() or any other function name). When we execute a C++ program, execution always begins at the beginning of the main() function. If you don’t have main(), your program will be compiled successfully, but it will not run and the compiler will report that you have not defined a main() function. That’s why every C++ program begins with a function named main(). In last remember that your program is not allowed to call the main() function explicitly. It is called implicitly by the compiler.
The C++ Preprocessor Directives: #include
Like C, C++ uses a preprocessor. A preprocessor is a program that processes a source file before the main compilation takes place. C++ handles directives whose names begin with a number sign #. We don’t need to do anything special to invoke this preprocessor. It is invoked automatically when we compile the program.
In the program article1.cpp, we have used the following preprocessor directive: #include.
The #include directive tells the compiler to include a different source-code file in your program. This directive tells the compiler to add the contents of the iostream.h file into our source file. This action of preprocessor is similar to pasting a block of text data into a document with your word processor.
Now the question arises – why add the contents of the iostream.h file to the program? The iostream.h describes classes, functions, and global values used for console input/output. The iostream.h stands for input–output stream. By input we mean the information brought into the program and output sends out the information from the program. We can receive information either from a standard input device, keyboard, or from a file. Similarly we can send information either to a standard output device, VDU, or to a file.
The iostream.h defines cin object to receive information from a standard input device and cout object to send information to a standard output device. That’s why it is necessary for the programs that use cin and cout for input and output, to include the iostream.h file. Without its inclusion, the compiler would not recognize cin and cout objects. The files with .h extension are referred as header files.
The filename in the #include directive is enclosed by angle brackets, that is ‘’ (greater than symbol). This usage identifies header files that compiler system provides. However if you want to include your own header files then you would surround these user-defined header files within double quotes (“ …. “). In C, the inclusions of header files are often optional; whereas in C++ they are always necessary.
The Standard Output Stream: cout
In program article1.cpp, the statement
cout << “Nobody is greater than God”;
writes the string constant, which is the character sequences between double quotes, to the console. In this statement, the cout variable is the C++ standard output stream object that writes the data to the console. You might have already listen the word – stream. A stream is an abstraction that refers to a flow of data. By default the standard output stream is associated with the monitor. Also it can be associated with other output devices.
The << operator is the output operator, also called as insertion operator. The insertion operator inserts data, which is on its right side into the output stream, which his on its left side. Thus the insertion operator points symbolically from what is being sent to where it is going. In the above statement the string constant is being written to the cout object that displays data on the monitor. You can also think of cout as an output device. Later on, you will learn how to display other data types.
White Spaces
Like C, C++ also is a free-form language, which means that C++ compiler ignores white-space characters – newline characters, spaces, tabs and blank lines completely. These characters are invisible to the compiler. Except for the rare occasion when two tokens are separated by a space or inside string constants. Actually your program does not need any type of white spaces to compile. Thus the program article1.cpp looks like this without white spaces:
#include
void main () {cout << “Nobody is greater than God”; }
This program will certainly compile and run correctly. But without white spaces it is rarely hard to read most programs. Therefore programmers often use white spaces to indent and separate code in various styles to make their programs more readable. There are so many ways for writing a C++ program. There is no hard and fast rule. Therefore choose a style that works for you, make it legible and be consistent in its use.