Lecture
No.08
01.1. Member Functions
•
Member
functions are the functions that operate on the data encapsulated in the class
•
Public
member functions are the interface to the class
01.2. Defining Member Functions
We
can define member functions in two ways,
- We can define
member functions of the class inside the class definition when we define
any class in our program.
OR
- We declare
member function inside the class definition and declare them outside the
class.
In
this case class definition is added in ClassName.h file and class
implementation code is added in ClassName.cpp file.
Function
definition inside the class:
General
Syntax:
class
ClassName {
…
public:
ReturnType
FunctionName() {
…
};
|
Example:
Define
a class of student that has a roll number. This class should have a function
that can be used to set the roll number
class
Student{
int
rollNo;
public:
void
setRollNo(int
aRollNo){
rollNo
= aRollNo;
}
};
|
Function definition outside class
General
Syntax:
class
ClassName {
…
public:
ReturnType
FunctionName();
};
ReturnType ClassName::FunctionName()
{
…
} |
Example
class
Student{
…
int
rollNo;
public:
void
setRollNo(int
aRollNo);
};
void
Student::setRollNo(int
aRollNo){
…
rollNo = aRollNo;
}
|
01.3. Inline Functions
·
Inline
functions is a way used by compilers to improve efficiency of the program, when
functions are declared inline normal process of function calling (using stack)
is not followed instead function code is added by compiler at all points where these functions have been
called. Basic concept behind inline functions is that they are functions in our
code but in compiler generated files these functions code is added by compiler
at all places where they were called in the code.
·
Normally
small size functions that need to be called many times during program execution
are declared inline. Inline functions decrease the code execution time because
program in their case doesn’t involve function call overhead.
·
Keyword
‘inline’ is used to request compiler to make a function inline.
·
However
using inline keyword with function doesn’t guarantee that function will
definitely in inlined, it depends on the compiler if it finds it can make
function inline it does so otherwise it ignores the keyword inline and treat
the function as normal function.
Example
inline int Area(int
len, int hi)
{
return len * hi;
}
int main()
{
cout << Area(10,20);
}
|
Inline Functions
The
functions defined inside the class are by default inline (whether we mention
keyword inline with them or not)
In
case we define function outside the class then we must use the keyword ‘inline’
to make the function inline.
However
compiler decides whether it will implement these functions code as inline or
not.
Example
Inline
function inside the class:
class Student{
int rollNo;
public:
void setRollNo(int
aRollNo){
…
rollNo = aRollNo;
}
};
|
Example
Inline
function outside the class:
class Student{
…
public:
inline void setRollNo(int
aRollNo);
};
void Student::setRollNo(int
aRollNo){
…
rollNo = aRollNo;
}
|
class Student{
…
public:
void setRollNo(int
aRollNo);
};
inline void Student::setRollNo(int aRollNo){
…
rollNo = aRollNo;
}
|
class Student{
…
public:
inline void setRollNo(int
aRollNo);
};
inline void Student::setRollNo(int aRollNo){
…
rollNo = aRollNo;
}
|
01.4. Constructor
Constructor is used to initialize
the objects of a class. Constructor is used to ensure that object is in well
defined state at the time of creation.
The constructor of a class is automatically
generated by compiler however we can write it by our self also.
Constructor is automatically called when
the object is created. Constructors are not usually called explicitly by us.
01.5. Constructor Properties
•
Constructor
is a special function having same name as the class name
•
Constructor
does not have return type
•
Constructors
are commonly public members
Example
class Student{
int
rollNo;
public:
Student(){
rollNo
= 0;
}
};
int main()
{
Student
aStudent;
/*constructor
is implicitly called at this point*/
}
We
can assure that constructor is called automatically by adding cout statement in
constructor as shown below,
#include <iostream>
using namespace std;
class Student{
int
rollNo;
public:
Student(){
rollNo
= 0;
cout<<”I
am constructor of Student class…\n”;
}
};
int main()
{
Student
aStudent;
/*constructor
is implicitly called at this point*/
system(“pause”);
return
0;
}
01.6. Default Constructor
•
Constructor
without any parameter or with all parameters with default values is called
default constructor
•
If
we do not define a default constructor the compiler will generate a default
constructor
•
Compiler
generated default constructor is called implicit and user written default
constructor is called explicit
•
This
compiler generated default constructor initialize the data members to their
default values
•
If
we have given any constructor for a class whether it is
•
our
own explcit default constructor ( i.e parameterless or with parameters having
default values )
or
•
our
own constructor with parameters
Then
compiler will not create implicit default constructor[1].
Example
Consider the class student
below it has no constructor so compiler will generate one for it,
class Student
{
int
rollNo;
char
*name;
float
GPA;
public:
… //no
constructors
};
|
Code of Compiler
generated implicit default constructor
{
rollNo =
0;
GPA =
0.0;
name =
NULL;
}
|
01.7. Constructor Overloading
We
can write constructors with parameters as well. These parameters are used to
initialize the data members with user supplied data (passed as parameter). The
example is shown below, here example Student class has four constructors their prototypes
are,
- Student(); /* explicit default parameterless constructor
*/
- Student(char * aName); /* constructor with one parameter* /
- Student(char * aName, int aRollNo); /* constructor with
two parameters */
- Student(int aRollNo, int aRollNo, float aGPA); /* constructor with
three parameters */
Example
class
Student{
int rollNo;
char *name;
float GPA;
public:
Student(); /* explicit default constructor */
Student(char * aName); /* constructor with one parameter* /
Student(char * aName, int
aRollNo); /* constructor with two
parameters */
Student(int aRollNo, int aRollNo,
float aGPA); /* constructor with three
parameters */
};
Student::Student(){
rollNo = 0;
name = NULL; // to indicate it is
pointing to nothing at this moment otherwise it can generate erroneous code.
GPA = 0.0;
}
Student::Student(int
aRollNo){
if(aRollNo < 0){
rollNo = 0;
}
else {
rollNo = aRollNo;
}
name
= NULL;
}
Student::Student(int
aRollNo,
char
* aName){
if(aRollNo < 0){
rollNo = 0;
}
else {
rollNo = aRollNo;
}
if (strlen(aName) > 0)
{
name = new
char[strlen(aName)+1];
strcpy(name,aName);
}
else
{
name
= NULL;
}
}
|
We
can create this Student class object using any one of these constructors as
follows,
int
main()
{
Student student1; // default constructor will be used
Student student2(“Name”); // one
parameter constructor will be used
Student student3(”Name”, 1); // two parameter constructor will be used
Student student4(”Name”,1,4.0); //
three parameter constructor will be used
}
|
01.8. Constructor Overloading
We
can use default parameter values to reduce the writing effort in that case we
will have to write only one constructor and it will serve the purpose of all
constructors as given below,
Example
Student::Student( char * aName = NULL, int aRollNo= 0, float aGPA = 0.0) {
…
}
|
It
is equivalent to all three constructors,
Student();
Student(char * aName);
Student(char * aName, int aRollNo);
Student(char * Name, int aRollNo, float
aGPA);
It
will use default values if values are not passed as arguments while creating
objects) it is described in code given below,
int
main()
{
Student student1; /*char * aName = NULL, int aRollNo= 0, float aGPA = 0.0*/
Student student2( “Name” ); /*char * aName = Name, int aRollNo= 0, float
aGPA = 0.0*/
Student student3( ”Name”, 1 );
/*char * aName = Name, int aRollNo= 1, float aGPA = 0.0*/
Student student4( ”Name”, 1 , 4.0); /*char * aName = Name, int aRollNo= 1,
float aGPA = 4.0*/
}
|
Copy
constructors are used when:
•
Initializing
an object at the time of creation (we want to create an object with state of a
pre existing object)
•
When
an object is passed by value to a function (As you know temporary copy of
object is created on stack so we need copy constructor to create that temporary
object with the state of actual object being passed).
Example
void func1(Student
student){
…
}
|
int main(){
Student studentA;
Student studentB = studentA;
func1(studentA);
}
|
Copy Constructor
(Syntax)
Student::Student( const
Student &obj){
/*copying values to newly created
object*/
rollNo = obj.rollNo;
name = obj.name;
GPA = obj.GPA;
}
|
As
was the case with default constructor compiler also generates copy constructor
by itself however we can override that copy constructor by writing our own copy
constructor as shown in example below,
#include <iostream>
using namespace std;
class Student{
int rollNo;
public:
Student(){
rollNo = 0;
cout<<”I am default constructor of
Student class…\n”;
}
Student(const Student
&obj){
cout<<”I
am copy constructor of Student class\n”;
rollNo = obj.rollNo;
}
};
int main()
{
Student aStudent;
/*default constructor is implicitly called at this
point*/
Student bStudent = aStudent;
/*copy constructor is implicitly called at this point*/
system(“pause”);
return 0;
}
|
01.10. Shallow Copy
•
When
we initialize one object with another then the compiler copies state of one
object to the other using copy constructor by assigning data member values of
previous object to newly created object.
Shallow copy using
default Copy Constructor (Syntax)
Student::Student( const
Student & obj ){
rollNo =
obj.rollNo;
name =
obj.name;
GPA =
obj.GPA;
}
|
•
This
kind of copying is called shallow copying
Example
Student
studentA;
Student
studentB = studentA; /*Shallow copy:
compiler will use copy constructor to assign studentA values to newly created
object studentB*/
|
Shallow
copy works fine if our class doesn’t include dynamic memory allocation but in
case of dynamic memory allocation it leads to dangling pointer problem as
explained below,
Problem is Shallow
Copy
Student
class data member name of char * type is added to store the name of student and
it is using dynamic memory according to the length of name entered by
user for student.
Object studentB is also pointing to memory
allocated object studentA for Student class data member name of char *
type, now there are two problems with this sort of copying,
Suppose we delete first object studentA for
some reason then its destructor will also free memory allocated by it hence
memory area containing name “AHMAD” will also be freed and will be given to
some other application by operating system, but studentB member name is
still pointing to that area so issue of “Dangling Pointer” will arose.
[Pointer pointing to incorrect memory location]. If we will try to print the
name of object studentB our program will terminate abnormally as it was
pointing memory of some other applications.
Secondly if for some reason we change name
of studentA the value of object studentB will also be changed as it pointing to
same memory location.
We resolve these two issues using deep
copy.
01.11. Deep Copy
We
write our own deep copy code in copy constructor so that when we create new
object from an existing object using copy constructor we also allocate new
dynamic memory for data members involving dynamic memory as shown below,
Student::Student( const Student & obj){
int
len = strlen(obj.name);
name
= new char[len+1];
// assignming new dynamic memory
to data member name of char * type for newly created object*/
strcpy(name,
obj.name);
…
//copy
rest of the data members in the same way
}
|
Example
Student studentA;
Student studentB = studentA; // now copy constructor will
perform deep copy (separate memory for both objects)
|
In
case our class doesn’t involve dynamic memory then default copy constructor
that performs shallow copy works fine.
In
case our class has any data member involving dynamic memory we have to write
our own code to do deep copy.
compiler generated default constructor is called implicit and user written
default constructor is called explicit
Post a Comment
Don't Forget To Join My FB Group VU Vicky
THANK YOU :)