|
|
|
|
|
|
|
|
|
|
|
Basics of C++.
|
|
|
It is probably best to look at concrete examples of object oriented programming in C++ before going into further theory or concepts. We'll consider two kinds of examples. The first will involve graphical and user interface objects, the second will involve reworking some old list ADTs as objects. |
|
|
|
|
|
Suppose we wanted to write a simple drawing program that could (among other things) display different shapes on the screen. The shapes to handle are circles and rectangles. They each have a position and size, though this will be defined differently for the different shapes. A circle will be defined by center point and radius, rectangle by a center point and the length and width. Shapes also have various characteristics such as colour. |
|
|
|
|
|
Useful methods for these objects include: Initialise; Move; SetColour; Draw. Initialise should set the position and size, while Move, SetColour and Draw should do the obvious. It should be clear that Initialise and Draw will be different for circles and rectangles, while SetColour and Move could be defined in a shape-independent way. (We'd also want methods to modify the size, but this won't be included in these tiny examples). |
|
|
|
|
|
The first thing to do in object oriented programming is decide on a class hierarchy - that is, a hierarchy of kinds of objects, from very general ones to very specific kinds. In this simple example we can have a general class of 'shapes' and more specific classes for 'circles' and 'rectangles' (a realistic program would of course have many more such classes). A particular circle with specific size, colour etc will be an instance of the circle class. We can now decide on which operations and datafields can be defined for the most general class (shape). The following gives the type definition, and an example method (assuming that the type ``ColourType'' is defined somewhere). |
|
|
|
|
|
class Shape { |
|
|
public: |
|
|
Move(int x, int y); |
|
|
SetColour(ColourType c); |
|
|
private: |
|
|
int xpos,ypos; |
|
|
ColourType colour; |
|
|
}; |
|
|
|
|
|
Shape::SetColour(ColourType c) |
|
|
{ |
|
|
colour = c; |
|
|
} |
|
|
|
|
|
Note that in the SetColour function 'colour' is not treated as a global variable, but as the value of the colour field of the object whose colour is being set. We can also access these fields when calling further functions within the function (e.g., we could call a function MovePen(xpos, ypos) and the x and y position of the object in question would be accessed, without these needing to be specified as arguments to the function.) Note too that the position and colour of the shape are `private' and can only be accessed or modified via any defined operations. |
|
|
|
|
|
Now, a circle and a rectangle are both kinds of shape. To specify this we can use the notation ': Shape' after the class name. For reasons to be explained later, we need here to specify `: public Shape'. So for circle and rectangle we might have: |
|
|
|
|
|
class Circle : public Shape { |
|
|
public: |
|
|
Circle(); |
|
|
Draw(); |
|
|
private: |
|
|
int rad; |
|
|
}; |
|
|
|
|
|
class Rectangle : public Shape { |
|
|
public: |
|
|
Rectangle(); |
|
|
draw(); |
|
|
private: |
|
|
int width, length; |
|
|
}; |
|
|
|
|
|
Circle and rectangle would inherit the operations and datafields from Shape, so it is not necessary to repeat them. I'll just assume that the relevant operations can be straightforwardly written. Note that the class 'Shape' is not a class that you'd have instances of. It is just defined so that specific shapes like circle and rectangle can be defined much more simply. Such classes are referred to as abstract classes. |
|
|
|
|
|
If we now had an object instance Ob of type Circle, and wanted to set its colour, we could call Ob.SetColour. It would use the SetColour function inherited from Shape. We can think of this as sending a message SetColour to the object Ob. |
|
|
|
|
|
Now, suppose we wanted to deal with a specialised kind of rectangle: say, a rounded rectangle (one with rounded corners). This can use the standard rectangle's initialise method, but will need a special draw method. |
|
|
|
|
|
class RoundedRectangle : public Rectangle { |
|
|
public: |
|
|
Draw(); |
|
|
} |
|
|
|
|
|
The new Draw procedure will override, or replace, the one that would be inherited from the standard rectangle object. |
|
|
|
|
|
Structure of a C++ program.
|
|
|
|
|
|
|
|
|
|
|
|
Variables. Data types. Constants.
|
|
|
|
|
|
Operators.
|
|
|
|
|
|
Communication through console.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|