420 likes | 436 Views
Learn about classes and objects in programming, including their attributes, methods, and the process of instantiation. Understand the difference between classes and objects, as well as the use of constructors. Explore the limitations and benefits of default and user-defined constructors.
E N D
Classes & Objects Lecture-6
Classes and Objects A class is a 'blueprint' for all Objects of a certain type (defined by ADT) class defines the attributes (data) and operations (methods) The class may be considered as an object factory allowing us to define objects of the same type. A single ADT allows us to make as many instances of a class as required
State Identity and Behavior A class is defined by the following 3 attributes A unique name, Attributes and Methods An Object is defined by Identity, State and Behavior The properties of the Class relate to the properties of the object Class attributes == Object state data Class Methods == Object behavior However Class name and Object identity are more complex
Object Name object are identified by unique names especially if only a few are created However if objects are constantly created and destroyed naming becomes more difficult In a program if many objects are created and destroyed at runtime the object is identified by it's memory location Objects which are predictable are identified by a unique name. Objects which are not are identified by there memory location and hence we use pointers. “when it rains there are many raindrops, it would be stupid to name each rain drop individually, so a rain drop may be identified by the space it occupies”
Difference between Classes and Objects Once defined, a class exists all the time the program is running, Objects may be created and destroyed For a single class there may be any number of objects instantiated at any one time A class has a unique name, attributes and methods. An Object has identity, state and behavior A class provides no state values for the object attributes. These can only be given values when applied to specific objects
Constructors When an object is created there are certain processes which must take place Instantiation always involves the allocation of memory for the objects state data. The methods do not require any memory as these are consistent for all objects of the class and are handled in the class itself. The special method which allocates the memory for an object is know as the 'constructor'
Constructors There are three basic types of constructor The default constructor User defined Constructor The Copy Constructor
The Default Constructor The default constructor takes no parameters (or return type) It performs no processing on the object data just memory allocation It will always be called by the compiler if no user defined constructor is provided The default constructor is not referred to by the programmer in the class definition
User Defined Constructor These constructors may be used to pass parameter values to the object These may be used to set default object values It is possible to have more than one constructor in a class passing different parameters This is known as overloading and gives more flexibility to the way the object can be instantiated
The Copy Constructor The copy constructor allows a new object to be created as a copy of an existing object. e.g. Therefore all of the objects state data is copied to the new object This object will be identical to the first except for it's identity This remains until methods are called on the new object to change the data object2 = object1;
Instantiating an Object To instantiate an object the abstract data type is called upon (class) This is like a normal data type (such as int, float, char, etc) However with the ADT we use the class name, for example with last weeks class Would create an object called point of class type Point2D However with classes we can instantiate many objects for example Point2D point; Point2D point1; Point2D point2; Point2D point3;
Sending Messages by using Methods The private data in a class can only be modified by using methods To call a method on an object we must refer to the object by name (and the specific instance) For Example: This calls the SetX method for the class to which point1 belongs to and sets the x attribute to 4.56 This is know as sending a message to the object and only methods contained in the public area of the class may be called. point1.setX(4.56);
Limitations of Default Constructor In the previous example the default constructor is called by the code Point2D point1; However this is not defined in the default class so the compiler takes care of it. However if we wish to give the object a default set of values we have to call methods for each object to set it. These limitations may be overcome by creating user defined constructors Point2D point1;
Coding a Constructor A C++ constructor has three important aspects It takes the same name as the class It may take arguments It cannot return a value For example the Point2D Class constructor would be class Point2D { ........... public : Point2D(); ........... }; Point2D::Point2D() { x = 0; y = 0; };
What to put in the Constructor Usually initialization code is put in the constructor As shown in the previous slide Now every time the object is created the current point is set to a useful default value (0,0) However sometimes this is not applicable to the program requirements
Parametrized Constructor As mentioned previously parameters can be passed to the constructor for example class Point2D { ........... public : Point2D(); Point2D(float Xin, float Yin); ........... }; Point2D::Point2D(float Xin, float Yin); { x = Xin; y = Yin; };
Default Parameter Values The above example may be modified to give a default value for example This means that if the Point2D constructor is called with no value it will default to [0.0,0.0] however this method may be overridden by using another value. For example Will construct a new class with a default value of [4.0,12.0] Point2D(float Xin=0.0,Yin=0.0); Point2D point(4.0,12.0);
User Defined Copy Constructor A programmer may also create a copy constructor by passing a reference to the object to be copied for example & denotes pass by reference and the const prefix indicates that the object being passed in must not be modified The code for the copy constructor may look like this Point2D(const Point2D &tocopy); Point2D::Point2D(const Point2D &tocopy) { x = tocopy.x; y = tocopy.y; }
Clean-up and Garbage Collection The default constructor is used to allocate memory for the creation of the Object The default destructor is used to de-allocate this memory With a static object this is done implicitly however for dynamic objects this must be done by the programmer This now allows us to determine exactly the life-cycle of the object by being able to control both the creation and destruction of the object
Defining a destructor method The destructor method may be defined to add extra functionality to the destruction of an object It has certain characteristic which mark it out from the other methods as follows It takes the same name as the class, preceded by the 'tilde' character ~ It cannot take arguments It cannot return a value
Copy Constructor with dynamic memory If we have dynamic memory in our classes we must copy the contents of the memory into a new class when using the = This is done with the copy constructor as follows
Copy Constructor with dynamic memory #ifndef __TEST_CLASS_H__ #define __TEST_CLASS_H__ class TestClass { private : int *mem; int Size; public : TestClass(); TestClass(int Size); TestClass(const TestClass& in); ~TestClass(); void Print(void); int size(void){return Size;} int& operator [] (int index) { return mem[index]; } //non-const }; #endif;
Copy Constructor with dynamic memory #include "TestClass.h" #include <iostream> #include <string.h> // for memcpy using namespace std; TestClass::TestClass() { Size=0; mem=NULL; } TestClass::TestClass(int size) { mem = new int[size]; Size = size; } TestClass::TestClass(const TestClass& in) { Size=in.Size; mem = new int[Size]; for(int i=0; i<Size; ++i) { mem[i]=in.mem[i]; } }
Copy Constructor with dynamic memory TestClass::~TestClass() { if(mem !=NULL) delete [] mem; } void TestClass::Print(void) { for(int i=0; i<Size; i++) cout<<"Mem["<<i<<"]="<<mem[i]<<endl; }
Copy Constructor with dynamic memory #include <iostream> #include "TestClass.h" using namespace std; int main(void) { TestClass A(10); for(int i=0; i<A.size(); i++) A[i]=i; A.Print(); TestClass B=A; B.Print(); return 1; }
Operators Overloading Operator Overloading means making the compiler's built in operator symbols work with classes Operator symbols are things like + - = * etc We saw how these work with data types such as int float etc We can also do this with variable of different types by the use of coercion To do this with classes we may want to use a syntax as follows Object3 = Object1 + Object2
So how do we do this? To allow a similar operation as shown previously we have to code the mechanism ourselves In effect the + and = operator must be overloaded to be methods of the class By overloading operators in this way we can give the classes in a system a common interface, allowing us to perform similar operations on a range of different objects.
Overloading and the assignment Operator The = operator is already overloaded to work with objects as well as simple data types This has already been see with the copy constructor This means that object2 is instantiated with the same state as object1, We can also do this in normal code for example class_name object1 = object2; object1 = object2;
Overloading and the assignment operator This behavior is default for the = operator however we can program our own overloaded = operator within the class. This is required when pointers are used as the object will point only to the memory address and if the initial object is destroyed so will the memory address where the pointer points to, Therefore code will be required to create and copy the pointer data
Overloading operators for a class Assignment (=) is a fundamental operation of all classes and types, therefore it is provided by the compiler However no default behavior is provided for the other operators when used with classes Other operations must be specified by the programmer in the class Consider the class below Colour -R: float -G: float -B: float -A: float • The class could possibly require a + operator to add two colours together or a - operator to subtract them. +Colour(r,g,b,c) +Colour + (Colour) ++=Colour
C++ Syntax The syntax required for operator overloading is : The operator keyword And one of the 40 operator which may be overloaded as shown below new delete + - * / % += -= *= /= %= ++ -- = ^ & | ~ ^= &= |= << >> >>= <<= < > == != <= >= ! && ||->* -> , comma operator () function call operator [] subscripting operator
class Point2D { private : float x; float y; public : void SetX(float Xin); float GetX(void); float GetY(void); }; void Point2D::SetXY(float Xin,float Yin) { x = Xin; y = Yin; } void Point2D::GetX(float Yin) { return x; } float Point2D::GetY(void) { return y; } The default assignment operator
A Simple Program #include”Point2D.h” #include<iostream> use namespace std; int main(void) { Point2D point, point2; point1.setXY(201,213) point2 = point1; cout << point1.x << “ “ << point1.y << endl; cout << point2.x << “ “ << point2.y << endl; }; Program Output 201 413 201 413
Syntax for Operator Overloading The syntax for operator overloading is as follows return_type operator symbol(parameter list ...) • The return type for a relational operator is a Boolean value return true or false object1 object2 if( > ) Object using Operator Parameter objects
Arithmetic Operator Overloading However arithmetic operators return an object of the appropriate class as shown below a temporary object is returned from the operator method object object object = + Object to receive results Object using Operators Parameter Operators
The parameter List The parameter list usually consists of an object of the class This is passed by reference rather than by value to avoid making a copy of the object Therefore the const prefix is used to stop the reference object being modified in the class For example we may have the following: less than (relational) int operator < (const Object &object); minus (arithmetic) Object operator -(const Object &object);
Overloading relational operators These are the easiest to implement as they only return Boolean values Using the previous Point Class we can add an equality operator (==) bool operator == (const Point &rhs); • And the method itself bool Point::operator==(const Point& rhs) { return (x==rhs.x && y==rhs.y) }
Using the relational operator In the code we can now write the following if(point1 == point2) cout << "points are the same" <<endl; else cout << "points are different"<<endl;
Overloading Arithmetic Operator As mentioned previously the arithmetic operator must return an object of the same class So for an + Point operator we would do the following Point operator + (const Point &rhs) • and for the method Point Point::operator +(const Point &rhs) { return Point(x+rhs.x,y+rhs.y); }
Using arithmetic Overloading Now we can add two Point classes together using the following syntax Point point1,point2,point3; point3 = point1+point2; • Now the object point3 contains the sum of the x points and the y points of objects point1 and point2.
Overloading the insertion and extraction operators (1) To overload the insertion and extraction operators we need to declare the following in the .h file friend std::ostream& operator<<(std::ostream& output, const Point3& s); friend std::istream& operator>>(std::istream& output, Point3 &s);
Overloading the insertion and extraction operators (2) And in the cpp file the actual methods ostream& operator<<(ostream& output, const Point & s) { return output<<"["<<s.x<<","<<s.y<<","<<s.z<<"]"; } istream& operator>>(istream& input, Point &s) { input >> s.x >>s.y >>s.z; return input; } • we can now use these in code Point3D point1; cin >> point1; cout << point1<<endl;