The document discusses class and object-oriented programming concepts such as classes, objects, member functions, and constructors. It provides examples of class declarations and definitions, and how to create objects and call member functions. The document also covers constructors, initializer lists, destructors, function templates, and class templates.
2. Outline
Class and Object
Constructor
Constructor Initializer List
Destructor
Default Initialization Values
Function Templates
Class Templates
2
3. Class
A class is a programmer-defined data type. It
consists of data and functions which
operate on that data.
Placing data and functions together into a
single entity is the central idea of object-
oriented programming.
3
4. Class Declaration Syntax
class Name // usually capitalized
{
public:
public members; // usually functions
private:
private members; // usually variables
};
Note
4
5. Example of a Class Declaration
#include<iostream>
using namespace std;
class ASimpleClass //declare a class
{
private:
int data; //a private member
public:
void setData(int item)
{
data = item;
}
void displayData()
{
cout<<"Data is : "<<data<<endl;
}
}; //program continues … 5
6. Example of a Class Declaration
void main()
{
ASimpleClass asp; //creates an object
asp.setData(10); //member access using dot operator
asp.displayData();
asp.setData(20);
asp.displayData();
}
Output
Data is : 10
Data is : 20
Press any key to continue
6
7. A Few Terms
class
class member
data member
member function
class object (class instance)
7
8. Objects
An object is an instance of a class.
Similarity:
int row;
This creates an instance of int called “row”.
8
9. Calling Member Functions
asp.setData(10);
asp.displayData();
These two statements are not like normal function calls.
This strange syntax is used to call a member function that is
associated with a specific object.
A member function must always be called in connection with an
object of the class.
Because a member function is always called to act on a specific
object, and not on the class in general.
The dot operator connects the object name and the member
function.
Dot operator is also called class member access operator.
9
10. Working with Objects
ASimpleClass asp1,asp2;
asp1.setData(10);
asp2.setData(20);
ASimpleClass
int data
void setData();
void displayData();
Two objects of ASimpleClass
data data
10 20
asp1 asp2
10
11. Part Example
#include<iostream> partno=pn;
using namespace std; cost=c;
class Part }
{ void showPart()
{
int modelno;
cout<<"Model :
int partno; "<<modelno<<endl;
float cost; cout<<"Part :
public: "<<partno<<endl;
void setPart(int mn, int pn, cout<<"Cost : "<<cost<<endl;
float c) }
{ }; //program continues …
modelno=mn;
//continues on right side… 11
12. Part Example Cont…
void main()
{
Part part;
part.setPart(555,100,100);
part.showPart();
}
Output
Model : 555
Part : 100
Cost : 100
Press any key to continue
12
13. Constructor
Setters provide a way of initializing class data
members.
However, sometimes it is convenient that an object
can initialize itself when it is created, without the
need to call setters.
13
14. Constructor
Automatic initialization is carried out using a special
member function called a constructor.
A constructor is a special member function provided
to allow initialization of variables.
Constructor is executed automatically whenever an
object is created.
14
15. Counter Example (with constructor)
//counter.h
class Counter
{
private:
unsigned int count;
public:
Counter() {count=0; } //constructor
void incCount();
unsigned int getCount();
};
15
16. Counter Example (with constructor)
//counter.cpp
#include"counter.h"
unsigned int Counter::getCount()
{
return count;
}
void Counter::incCount()
{
count++;
}
16
17. Counter Example (with constructor)
//driver.cpp
#include"counter.h"
#include<iostream>
using namespace std;
void main() {
Counter c; //creates an object and initializes count
cout<<c.getCount()<<endl;
c.incCount();
cout<<c.getCount()<<endl;
}
17
18. Constructor
Must have the same name as the class itself
Name is one way the compiler recognizes them as
constructors.
Do NOT have a return type (not even void)
Why not?
Since the constructor is called automatically by the
system.
This is the 2nd way the compiler knows they are
constructors.
18
19. Default Constructors
Default constructor
parameter-less constructor, it initializes the variables
to some default value, such as zero
Example
TimeType();
Student();
19
21. Default Constructors
An implicit default (no-argument) constructor is built
into the program automatically by the compiler.
This constructor is used to create the objects when
we don’t write a constructor.
21
22. Initializer List
Counter():count(0)
{
} //constructor
Is equivalent to
Counter()
{
count=0;
}
Initialization takes place following the member function declaration
but before the function body.
It is preceded by a colon
The value is placed in parentheses following the data member.
22
23. Initializer List
Initializer list is also called member-initialization list.
If multiple members are to be initialized, they are
separated by commas.
Example
someClass():m1(5),m2(42),m3(3) { }
Actions complicated than simple initialization must
be carried out in the constructor body.
23
24. Overloaded Constructors
A default constructor initializes data members at default values
such as zero.
Example
Distance() : feet(0),inches(0.0){ } //default constructor
It is convenient to be able to give data members a value (other
than default value) when the objects are created.
Example
Distance dist1(5,6.25);
Defines a Distance object named dist1 and initializes feet
at 5, and inches at 6.25
For this, we need a constructor like this:
Distance (int f, float i) : feet(f),inches(i) { }
24
25. Overloaded Constructors
We have two constructors for Distance
Distance() : feet(0),inches(0.0) { }//default constructor
Distance(int f, float i) : feet(f),inches(i) { }
These two explicit constructors with the same name Distance
makes the constructor overloaded.
Which of these is executed to create an object depends on
how many arguments are used in the object creation.
Distance dist1;//calls default constructor
Distance dist2(11,6.25); //calls constructor with two
arguments
25
26. The Default Copy Constructor
We have seen two variations of constructor.
There is another way of initializing a constructor.
An object can be initialized with another object of the same type.
This type of constructor falls in the category of implicit
constructors.
We don’t need to create a constructor for this.
One is already built into all classes.
It is called the default copy constructor.
It is one argument constructor whose argument is an object of
the same class as the constructor.
26
27. The Default Copy Constructor
Default copy constructor can be invoked in two ways:
Example:
Distance dist1(11, 6.25);
Distance dist2(dist1); //calling default copy constructor
Distance dist3=dist1; //calling default copy constructor
Both the ways have the same results and causes a member-to-
member copy
The second way looks like an assignment statement, but it is not.
Both the formats invoke the default copy constructor.
27
28. Destructors
Another function is called automatically when an object is
destroyed.
Such a function is called a destructor.
Destructor has the name as the constructor (i.e. the class name)
but is preceded by a tilde (~).
The most common use of destructor is to de-allocate memory
that was allocated for the object by the constructor.
28
29. Destructors
~Classname( )
A default do-nothing destructor is provided by the
compiler.
Only one destructor per class
No arguments
No return type
29
30. Templates
C++ supports code reuse in different ways.
The template feature in C++ provides way to reuse
source code.
The concept of Template is applicable to:
Functions
Classes
30
31. Function Templates
Suppose we want to write a function that returns the absolute
value of a number.
Ordinarily, this function would be written for a particular data
type:
int abs(int n) // absolute value of ints
{
return (n<0) ? -n : n; // if n is negative, return –n
}
Here the function is defined to take an argument of type int and
to return a value of this same type.
31
32. Function Templates
But now suppose we want to find the absolute value of a type
long.
We need to write a completely new function:
long abs(long n) // absolute value of longs
{
return (n<0) ? -n : n;
}
And again, for type float:
float abs(float n) // absolute value of floats
{
return (n<0) ? -n : n;
}
32
33. Function Templates
The body of the function is same in each case, but they must be
separate functions because they handle variables of different
types.
It’s true that in C++ these functions can all be overloaded to have
the same name, but we must nevertheless write a separate
definition for each one.
Rewriting the same function body over and over for different
types wastes time as well as space in the listing.
33
34. Function Templates
Also, if we find we’ve made an error in one such function, we’ll
need to remember to correct it in each function body.
Failing to do this correctly is a good way to introduce
inconsistencies into our programs.
It would be nice if there were a way to write such a function just
once and have it work for many different data types.
This is exactly what Function templates do for us.
34
36. Function Templates
The key innovation in function templates is to represent the data
type used by the function not as a specific type such as int, but by a
name that can stand for any type.
In the function template above, this name is T.
The template keyword signals the compiler that we are about to
define a Function template.
The keyword class, within the angle brackets, might just as well be
called type.
As we’ve seen, we can define our own data types using classes, so
there’s really no distinction between types and classes.
The variable following the keyword class (T in this example) is called
the template argument.
36
37. Function Templates
What does the compiler do when it sees the template keyword and
the Function definition that follows it?
The function template itself doesn’t cause the compiler to generate
any code.
It can’t generate code because it doesn’t know yet what data type
the function will be working with.
It simply remembers the template for possible future use.
Code generation doesn’t take place until the function is actually
called (invoked) by a statement within the program.
This happens in expressions such as abs(int1) in the statement
cout << "abs(" << int << ")=" << abs(int1);
37
38. Function Templates
When the compiler sees a function call, it knows that
the type to use is int, because that’s the type of the
argument int1.
So it generates a specific version of the abs()
function for type int, substituting int wherever it sees
the name T in the function template.
This is called instantiating the function template, and
each instantiated version of the function is called a
template function. 38
39. Function Templates
Notice that the amount of RAM used by the program
is the same whether we use the template approach
or write three separate functions.
What we’ve saved is having to type three separate
functions into the source file. This makes the listing
shorter and easier to understand.
Also, if we want to change the way the function
works, we need to make the change in only one
place in the listing instead of three.
39
40. Function Templates with Multiple
Arguments
Let’s look at another example of a function template.
This one takes three arguments: two template
arguments and one basic type.
The purpose of this function is to search an array for
a specific value.
The function returns the array index for that value if
it finds it, or -1 if it can’t find it.
The arguments are a pointer to the array, the value
to search for, and the size of the array.
40
41. Function Templates with Multiple
Arguments
template <class atype>
int find(const atype* array, atype value, int size) { Output
for(int j=0; j<size; j++) 'f' in chrArray: index=2
if(array[ j ]==value) return j; 6 in intArray: index=-1
return -1; 4 in dubArray: index=-1
}
int main() {
char chrArr[ ] = {'a', 'c', 'f', 's', 'u', 'z'}; // array
char ch = 'f'; // value to find
int intArr[ ] = {1, 3, 5, 9, 11, 13};
int in = 6;
double dubArr[ ] = {1.0, 3.0, 5.0, 9.0, 11.0, 13.0};
double db = 4.0;
cout << "n 'f' in chrArray: index=" << find(chrArr, ch, 6);
cout << "n 6 in intArray: index=" << find(intArr, in, 6);
cout << "n 4 in dubArray: index=" << find(dubArr, db, 6);
return 0;
} 41
42. Template Arguments Must Match
When a template function is invoked, all instances of the same
template argument must be of the same type.
For example, in find(), if the array is of type int, the value to
search for must also be of type int. We can’t say
int intarray[ ] = {1, 3, 5, 7}; // int array
float f1 = 5.0; // float value
int value = find(intarray, f1, 4); // error
Because the compiler expects all instances of atype to be the
same type.
find(int*, int, int); // It can generate a function
find(int*, float, int); // It can’t generate a function
Because the first and second arguments must be the same type.
42
43. Class Templates
The template concept can be applied to classes as
well as to functions.
Class templates are generally used for data storage
(container) classes.
Stacks and linked lists, are examples of data
storage classes.
43
44. Class Templates
The Stack class below, could store data only of type int.
class Stack
{
int st[10]; // array of ints
int top; // index number of top of stack
public:
Stack(); // constructor
void push(int var); // takes int as argument
int pop(); // returns int value
};
44
45. Class Templates
If we wanted to store data of type long in a stack, we would need
to define a completely new class.
class LongStack
{
long st[10]; // array of longs
int top; // index number of top of stack
public:
LongStack(); // constructor
void push(long var); // takes long as argument
long pop(); // returns long value
};
45
46. Class Templates
//Solution with a class template
template <class Type>
class Stack{
Type st[10]; // stack: array of any type
int top; // number of top of stack
public:
Stack(){top = 0;} // constructor
void push(Type); // put number on stack
Type pop(); // take number off stack
};
46
47. Class Templates
template<class Type>
void Stack<Type>::push(Type var) // put number on stack
{ if(top > 10-1) // if stack full,
cout<< "Stack is full!";
st[top++] = var;
}
template<class Type>
Type Stack<Type>::pop() // take number off stack
{ if(top <= 0) // if stack empty,
cout<< "Stack is empty!";
return st[--top];
}
47
48. Class Templates
int main() {
Stack<float> s1; // s1 is object of class Stack<float>
// push 2 floats, pop 2 floats
s1.push(1111.1);
s1.push(2222.2);
cout << "1: " << s1.pop() << endl;
cout << "2: " << s1.pop() << endl;
Stack<long> s2; // s2 is object of class Stack<long>
// push 2 longs, pop 2 longs
s2.push(123123123L);
s2.push(234234234L);
cout << "1: " << s2.pop() << endl;
cout << "2: " << s2.pop() << endl;
return 0;
} 48