In this tutorial, I will, hopefully, teach you about classes and how to use them. I will mostly be extending my answer to this question here: http://forum.codecal...2318-c-classes/.
The purpose of classes is to group data and behavior together. Consider, for example, a typical Car. It can have various attributes (called members or fields, which are just names for pieces of data), like size, liters-per-hour, speed, current fuel, etc. It also has some behaviors. For example, a Car can drive (change its position at the expense of fuel). A Car can also be refueled. As you can see, behaviors, or, from now on, methods, are functions that can manipulate data (or state, which are synonymous) of an object.
What is the difference between an object and a class, you might ask? Well, a class is something abstract; it merely describes an object. Objects are said to be instances of a class. Just like int describes a number: in the expression int a;, int would be the class, and a would be the instance of the said class. Therefor, you can think of classes as your own, custom data-types.
I've created this graphic to help illustrate the point:
So, enough with the talk, lets code! We will create a class called "Car", but this time, I will show the proper way of doing this, and explain it in detail.
#include <string> #include <iostream> using std::cout; using std::endl; using std::string; //This lets us use the name "string" instead of typing "std::string". class Car { string model; //Ford? Nissan? Whatever. int fuel; //How much fuel does the car have at this very moment? int tankSize; //How much fuel can fit in a car? int speed; //How many kilometers will the car travel in one hour? int litersPerHour; //How many liters does the car spend per hour of driving? int position; //Along a straight line, i.e. a road. In kilometers. public: //This is a constructor, which will be explained later. Car(string, int, int, int); //model, fuel, literPerHour, speed //tankSize is initially set to fuel. position is by default 0. //What can we do with a car? void drive(int); //Change the position at the rate of speed over the time which is provided as the argument (in hours). void refuel() { fuel = tankSize; } string getModel() { return model; } int getFuel() { return fuel; } int getPosition() { return position; } }; //This is the previously mentioned constructor. It does not have a return type. Car::Car(string modela, int fuela, int litersPerHoura, int speeda) { model = modela; fuel = fuela; speed = speeda; litersPerHour = litersPerHoura; position = 0; //All cars start at the position 0. tankSize = fuel; } //Void means that the function does not have a return type. void Car::drive(int hours) { //You can't go back in time, sorry. if (hours < 0) { return; } //If we have more fuel then needed... if (fuel > litersPerHour * hours) { position += speed * hours; fuel -= litersPerHour * hours; } else if (fuel > 0) //If there is at least some fuel left... { position += speed * (fuel/litersPerHour); //Spend it all. fuel = 0; } }
What you see above, is a declaration of a class, along with implementation of its method(s). The declaration and implementation are usually separated in C++, allowing you to get a feel of what a class does, without actually seeing how it does it (you see the names of the methods, their return types, and the types of their arguments, but you don't actually see the computation they perform). This isn't the case for simple, one-lined methods such as getters (that is why I included them inside the class declaration). It is also worth nothing that class names usually start with a capital letter, to distinguish themselves from normal function or variable names and keywords.
Access specifiers
One of the big differences between members of a class is their access level, which can be: 1) private (default), 2) public, and 3) protected (I wont be dealing with protected in this tutorial, but it is fairly simple and you can google it). All members (in this case, model, speed, position, etc) and methods (getters, drive, refuel) of a certain class are private by default. This means that these can only be accessed from the class itself, and not from outside objects. It's very useful for a concept called encapsulation, which is one of the basic principles behind OOP. It essentially dictates that all objects should hide their inner implementation (members and some methods), and expose only the necessary to other objects. The exposing is then done using the public keyword. This tutorial doesn't really focus on OOP design, a huge field per se, but only on classes, so I won't be covering why should you hide implementation and do all those other neat things. Maybe in another tutorial.
Constructors (and destructors)
These are very straightforward. Each time an instance of a class gets created (an object), the class' constructor function is called. If you want your classes to accept arguments, or if you want to do some kind of initialization, you can (and should) do it in a constructor. Contructors are very special functions, because they do not have a return type, and their name must be the same as the name of the class itself. If you do not create a custom constructor of your own, the compiler has to generate one for you, but if you create a constructor, the default (empty) constructor will not get generated. There is also another neat fact about constructors: you can have multiple of them! Each time you instantiate an object of your class, the compiler will check which constructor fits your call, and will use that one.
So the following code is valid:
... Car() Car(int, int) Car(int, string) ... Car car1; Car car2(2, 5); Car car3(6, "abrf");
All of these will use their respective constructors.
Now, about destructors. There can be only one! And, they're pretty analogous to the constructors, but aren't used for initializing, but deallocating any memory that the object reserved for itself. This usually only makes sense in when using pointers, so I will not speak of destructors much, only of their syntax. Like constructors, their name is also that of the class, but it is prefixed with a tilde, "~", and they do not return a type. So the destructor for our Car class would simply be named "~Car ()". They, as you've probably guessed already, get called when the object is being destroyed, which usually happens when functions (such as main) return.
Another thing you should probably know about constructors and destructors is that their access must be public.
Using classes
This paragraph will be short and simple, its purpose is just to explain how to use classes. The only thing which is actually important is accessing members and methods of objects. This is done via the dot operator, as demonstrated below. Just remember, that the dot operator can only access public members and methods!
int main() { Car car1("Ford", 200, 10, 50); //Create a new variable called "car1" that is an object, which is an instance of the class Car. cout << "Model: " << car1.getModel() << "." << endl; //"Ford" cout << "Position: " << car1.getPosition() << "km." << endl; //0 cout << "Fuel: " << car1.getFuel() << "L." << endl; //200 cout << endl; car1.drive(10); //Drive the car around for 10 hours. cout << "Position after driving: " << car1.getPosition() << "km." << endl; //500 cout << "Fuel after driving: " << car1.getFuel() << "L." << endl; //100 cout << endl; car1.refuel(); cout << "Fuel after refuel: " << car1.getFuel() << "L." << endl; }
To get the complete code used in this tutorial, simply copy-paste the first and the last snippet in the same file, respectively, and compile&run!