Snazzy title, eh? Well, not snazzy, but informative. As it suggests, this article (or tutorial, if you will) is all about OOP in the computer language C++. Okay, let's get to the intros. The name's Williams, Mike Williams. My mission? To teach novice programmers, such as yourselves about the art of programming. Through the months, I'm hoping to take you through a variety of programming techniques, starting right here, right now with C++. Are you sitting comfortably? Then I shall begin....
OOP is undoubtedly one of the most complex programming techniques to explain. In fact, it's not so much a 'technique' rather than a whole new method of looking at programming itself. There are entire books on the subject, and it's well beyond the scope of this article to introduce you to every philosophy and implication of OOP. To understand OOP, you must first understand what programming was like before OOP.
Back then, the basic definition of programming was this : a program is a sequence of logical instructions followed by the computer. And that's it. All well and good, but let's face it, it's hardly inspiring. Until now, that is. It's been hiding in the background for quite some time now, but OOP has finally taken off. In an OO programming language, the emphasis is placed far more on the data, or the 'objects' used and how the programmer manipulates them. Before OOP, numbers were simply an address in memory; a sequence of bytes that meant nothing. Now, however, through OOP they have become far more than that. The program is now a solution to whatever problem it is you have, but now it is done in the terms of the objects that define that problem, and using functions that work with those objects. Confused? Don't worry, you won't need to understand OOP to use it within your programs. Indeed, the best way to learn what OOP is all about is through using it in your programming.
All the examples within this article can be compiled in the GNU C++ compiler. To invoke it, type:
g++ <filename>
at the BASH prompt. I'm assuming that you have a reasonably up to date compiler, although it shouldn't make too much of a difference if you don't. Oh, and by the way, you can't use the GNU C compiler - it won't work (just thought I'd mention that.) You will, of course, need a text editor. 'Emacs' is a very powerful editor, and I suggest you use that.
This article is aimed at people who already have a reasonably understanding of the C++ language, but want to further that understanding by learning about OOP in C++. If you're a complete beginner, I suggest you read one of the hundreds of C++ tutorials lying around on the internet. A good place to start would be http://www.programmingtutorials.com/.Good luck.
Hundreds of years ago, in Britain (specifically England), there was civil unrest. People were angry - the poor people to be more specific. They noticed that some people were richer than them, they did not like it. What to do about this problem? How to keep the people happy? Religion had already gone some of the way, but even the promise of eternal utopia if the poor behaved themselves in life didn't seem to work. Capitalism already had sunk its powerful jaws into the world, and a new idea was needed to keep the masses happy. That idea became known as 'class'. The basis was that if everyone understood their place and role in society, they would feel secure and happy, and would not challenge the authority. It worked. There was the upper class (who were rich), the middle class (who were not so rich), and the poor sods class (who could barely afford to live). Quite unfair, but nevertheless it became reality. What has this got to do with C++ you ask? Well in C++, all Object Orientation comes in the form of classes. But enough of that; we're programmers, not social scientists.
Up to this point in your use of C++, you've used only the basic types of variables : int, float, bool, double, and so forth. These are called simple data types. However, they are very linear in what we can 'model' with them. Let's take an example. Let's say we wanted to represent a real life object, say a house. Obviously, we would have to examine the various attributes of a house : the number of rooms it has, its street number and whether or not it has a garden (okay, so there are more attributes, but I won't go into them now). In C++, we could show the house like this:
int number, rooms; bool garden;
And it would work fine for this particular example. But suppose we wanted many houses? Suppose we wanted to make the program more complicated than this? Suppose we wanted to define our own data type to represent the house. C++ allows us to do this through the use of classes.
Continuing with our example of the house, let's have a look at how we could 'model' a house using a C++ class:
class house { public: int number, rooms; bool garden; }; main() { house my_house; my_house.number=40; my_house.rooms=8; my_house.garden=1; return 0; }
Let's take a look at what each line does. The second line declares a new class and calls it 'house'. We then open the class definition with the curly brace '{'. The next line declares that all the 'members' (any data type that belongs to the class) that follow it to be 'public (I'll explain what this means later). We then go onto declare two variables of the basic type 'int' (integer). The next statement declares the garden member to be of type bool (booleon- either a 1 or a 0). Finally, we end the class with closing curly brace '}' and a ;. We have now declared a new data type or class called 'house', which we can use within our program. To use it, we start the main() function, which is where the execution of the program begins and ends. The first thing we do in the function is to declare the variable my_house to be of type house, which is the class we defined at the beginning of the program. Now, we this variable gains new dimensions; it now has many more attributes than a simply int or float type. From our class definition, we gave the house class three variables : number, rooms and garden. The variable we just declared, my_house, has all of these attributes. In the second line of our main function, we define the number member of the object my_house to be of value 40. We then go onto define the values for the other three data members of my_house, before ending the function with the return value 0.
At this point, you're sitting there wondering what the big fuss is about these classes. After all, wouldn't it be simpler to use the non-OO method? Well, it would in this particular instance, since we're only talking about a very small program that does very little. However, once you start to write more and more complicated programs, you will find not only that classes are useful, but that they are essential.
It's all well and good being able to declare a some variables, but how do we make use of them? The answer comes of course in functions. In C++, classes can have member functions. These are declared in a similar fashion to member variables. To illustrate how they work, let's take an example. A square perhaps. First we must model the data based on the attributes of a square. It has a length, a width, and of course an area. Of course, you find the area of a square by multiplying the length by the width. To do this, we could use a member function:
class square { public: int length, width; int area() { return length*width; } };
main() { square my_square; my_square.length=5; my_square.width=2; cout<<my_square.area(); return 0; }
This example should output the number 10. The square class is very similar to the house class we saw earlier. Firstly, we declare two member variables of type int : length and width. We then go onto declare a function, area(), which will return a int value. You declare the function exactly as you would outside a class. In this case, we make area() return the value of the member variables length and width when multiplied. We then end the class, and start with the main function, which should pretty much explain itself.
Of course, if you had a lot of functions to put in the class, they would all become rather messy. To overcome this, we use something called the scope resolution operator. Let's say we wanted to declare the area() function outside of our original function definition. Firstly, we would declare the class square, and in it the function area, as shown above. However, we would not insert the function code in at this point, so the class definition would look like this:
class square { public: int length, width; int area(); };
To define the member function area() outside of the class defintion, we would write this:
int square::area() { return length*width; }
This would produce the same output.
While we're on the subject of member function definitions, you should learn the difference between public and private members of a class. Members that are declared to be public can be accessed from any function within the entire program. The simplest way to explain is with an example. Suppose we declared the class square just like it was above, and tried to access the length variable from within the function main, which is not a member function of the class:
main() { sqaure my_square; my_square.length=2; cout<<my_square.length; return 0; }
The compiler would have no problem with this, and would output the value 2. However, let's say we change the square class so it looked like this, and all the members were private:
class square { private: int length, width; int area(); };
If we tried to run the function main() shown above, the compiler would generate an error. Private members can only be accessed through member functions.
It gets a bit tedious declaring the value of each member variable of a class using the method shown below:
main() { sqaure my_square; my_square.length=2 my_square.width=3 }
For each member of mysquare, we have to seperately declare and initialize its value. Of course, not only is this tedious, but it's also easy to overlook the initialization of each member, particularly when your classes become more complex. One way around this is to use a class constructor. A class constructor is a function that is initialized whenever the class is used:
class square { public: int length, width; square(int length1, int width1) { length=length1; width=width1; } int area() { return length*width; } }; main() { square my_square(5, 2); cout<<my_square.area(); return 0; }
This would produce the output 10. Firstly, we declare the class constructor by giving it the same name as the class itself. >From now on, this function will execute itself whenever the class is used. We declare it so that it takes two values, both of type int. The next change comes in the function main(). Whenever we delcare an object to be of type square, we add a function definition. In this case, we gave the variables length1 and length2 the values 5 and 2. The constructor then takes these two variables, and assigns their values to the member variables length and width, and, as they say, the rest writes itself.
It goes without saying that you can use arrays with classes. Obviously, this opens up scope for far declaring far more variables in a shorter time. There isn't a huge amount to go through on this subject, so let's take a simple example:
class person { public: int age, house_number; }; main() { person alex[5]; for(int x(0); x<5; x++) { alex[x].age=x; alex[x].house_number=x; cout<<"Age is "<<alex[x].age<<endl <<"House number is "<<alex[x].house_number<<endl; } return 0; }
There's nothing really complicated within this example, so I won't go through it. Obviously, you can do a lot more with arrays, and it doesn't take a genius to work out other ways to use them.
Well that's all for this month. If I get a chance, next week I'll continue this very topic, and go further into OOP programming with C++ to look at ideas such as pointers, class desctructors, inheritance and organizing your program code into files. Happy programming!
Oh, and one more thang...
If you have any comments/criticisms/flames about this article [or life in general ] please send them to me. I'll be more than happy to read them and respond, perhaps with childish name calling. Who knows.