C++ Notes Module 1
C++ Notes Module 1
Module 2
Introduction to classes and Objects 9hrs
Constructors can be defined either inside the class definition or outside class definition using class
name and scope resolution :: operator.
class A
{
int i;
public:
A(); //Constructor declared
};
Types of Constructors
Constructors are of three types:
Default Constructor
Parametrized Constructor
Copy Constructor
Default Constructor
Default constructor is the constructor which doesn't take any argument. It has no parameter.
Syntax :
class_name ()
{ classname(){ //Constructor Definition } };
Example :
class Cube
{
int side;
public:
Cube()
{
side=10;
}
};
int main()
{
Cube c;
cout << c.side;
return 0;
}
Output : 10
In this case, as soon as the object is created the constructor is called which initializes its data
members.
A default constructor is so important for initialization of object members, that even if we do not define
a constructor explicitly, the compiler will provide a default constructor implicitly.
class Cube
{
int side;
};
int main()
{
Cube c;
cout << c.side;
return 0;
}
Output : 0
In this case, default constructor provided by the compiler will be called which will initialize the object
data members to default value, that will be 0 in this case.
Parameterized Constructor
These are the constructors with parameter. Using this Constructor you can provide different values to
data members of different objects, by passing the appropriate values as argument.
Example:
class Cube
{
int side;
public:
Cube(int x)
{
side=x;
}
};
int main()
{
Cube c1(10);
Cube c2(20);
Cube c3(30);
cout << c1.side;
cout << c2.side;
cout << c3.side;
return 0;
}
OUTPUT : 10 20 30
By using parameterized constructor in above case, we have initialized 3 objects with user defined
values. We can have any number of parameters in a constructor.
Copy Constructor
These are special type of Constructors which takes an object as argument, and is used to copy values
of data members of one object into other object.
Syntax
class_name ( const class_name & ) {
// body of constructor
}
Example
#include<iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
Point(int x1, int y1) { x = x1;
y = y1; }
// Copy constructor
Point(const Point &p2) {
x = p2.x;
y = p2.y; }
int main()
{
Point p1(10, 15); // Normal constructor is called here
Muralidhara S, AP, Dept.of CSE
Object oriented programming with C++ 16CSE43
Constructor Overloading
Just like other member functions, constructors can also be overloaded. In fact when you have both
default and parameterized constructors defined in your class you are having Overloaded
Constructors, one with no parameter and other with parameter.
You can have any number of Constructors in a class that differ in parameter list.
class Student
{
int rollno;
string name;
public:
Student(int x)
{
rollno=x;
name="None";
}
Student(int x, string str)
{
rollno=x ;
name=str ;
}
};
int main()
{
Student A(10);
Student B(11,"Ram");
}
In above case we have defined two constructors with different parameters, hence overloading the
constructors.
One more important thing, if you define any constructor explicitly, then the compiler will not provide
default constructor and you will have to define it yourself.
Destructors
Destructor is a special class function which destroys the object as soon as the scope of object ends.
The destructor is called automatically by the compiler when the object goes out of scope.
The syntax for destructor is same as that for the constructor, the class name is used for the name of
destructor, with a tilde ~ sign as prefix to it.
class A
{
public:
~A();
};
class A
{
A()
{
cout << "Constructor called";
}
~A()
{
cout << "Destructor called";
}
};
int main()
{
A obj1; // Constructor Called
int x=1
if(x)
{
A obj2; // Constructor Called
} // Destructor Called for obj2
} // Destructor called for obj1
class Dual
{
int a;
public:
Dual(int x=0) // default arguments
{
a=x;
}
};
int main()
{
Dual obj1;
Dual obj2(10);
}
Here, in this program, a single Constructor definition will take care for both these object
initializations. We don't need separate default and parameterized constructors.
Pointers in C++
Pointer variable hold the address of another variable.
Example:
#include <iostream>
using namespace std;
int main ()
{
int var1;
char var2[10];
cout << "Address of var1 variable: ";
Here, type is the pointer's base type; it must be a valid C++ type and var-name is the name of the
pointer variable. The asterisk you used to declare a pointer is the same asterisk that you use for
multiplication.
However, in this statement the asterisk is being used to designate a variable as a pointer.
Following are the valid pointer declaration:
int *ip; // pointer to an integer
double *dp; // pointer to a double
float *fp; // pointer to a float
char *ch // pointer to character
Example:
#include <iostream>
using namespace std;
int main ()
{
int var = 20; // actual variable declaration.
int *ip; // pointer variable
ip = &var; // store address of var in pointer variable
cout << "Value of var variable: ";
cout << var << endl;
// print the address stored in ip pointer variable
cout << "Address stored in ip variable: ";
cout << ip << endl;
// access the value at the address available in pointer
cout << "Value of *ip variable: ";
cout << *ip << endl;
return 0;
}
When the above code is compiled and executed, it produces result something as follows:
Value of var variable: 20
Address stored in ip variable: 0xbfc601ac
Value of *ip variable: 20
We can define pointer of class type, which can be used to point to class objects.
class Simple
{
public:
int a;
};
int main()
{
Simple obj;
Simple* ptr; // Pointer of class type
ptr = &obj;
For accessing normal data members we use the dot . operator with object and -> with pointer to
object.
But when we have a pointer to data member, we have to dereference that pointer to get what it’s
pointing to, hence it becomes,
Object.*pointerToMember
and with pointer to object, it can be accessed by writing,
ObjectPointer->*pointerToMember
Example
class Data
{
public:
int a;
void print() { cout << "a is "<< a; }
};
int main()
{
Data d, *dp;
dp = &d; // pointer to object
d.*ptr=10;
d.print();
dp->*ptr=20;
dp->print();
}
Output :
a is 10 a is 20
The syntax is very tough, hence they are only used under special circumstances.
Syntax :
return_type (class_name::*ptr_name) (argument_type) = &class_name::function_name ;
class Data
{
public:
int f (float) { return 1; }
};
int main()
{
fp2 = &Data::f; // Assignment inside main()
Structures vs Classes
1) Members of a class are private by default and members of struct are public by default.
class Test {
int x; // x is private
};
int main()
{
Test t;
t.x = 20; // compiler error because x is private
getchar();
return 0;
}
// Program 2
#include <iostream>
struct Test {
int x; // x is public
};
int main()
{
Test t;
t.x = 20; // works fine because x is public
getchar();
return 0;
}
2) When deriving a struct from a class/struct, default access-specifier for a base class/struct is public.
And when deriving a class, default access specifier is private. (Inheritance will be discussed later)
For example program 3 fails in compilation and program 4 works fine.
// Program 3
#include <stdio.h>
class Base {
public:
int x;
};
int main()
{
Derived d;
d.x = 20; // compiler error becuase inheritance is private
getchar();
return 0;
}
// Program 4
#include <stdio.h>
class Base {
public:
int x;
};
int main()
{
Derived d;
d.x = 20; // works fine becuase inheritance is public
getchar();
return 0;
}
The stack: All variables declared inside the function will take up memory from the stack.
The heap: This is unused memory of the program and can be used to allocate the memory
dynamically when program runs.
Example:
#include <iostream>
using namespace std;
int main () {
return 0;
}
If we compile and run above code, this would produce the following result:
Consider you want to allocate memory for an array of characters, i.e., string of 20 characters. Using
the same syntax what we have used above we can allocate memory dynamically as shown below.
int ROW = 2;
int COL = 3;
double **pvalue = new double* [ROW]; // Allocate memory for rows
#include <iostream>
using namespace std;
class Box {
public:
Box() {
cout << "Constructor called!" <<endl;
}
~Box() {
cout << "Destructor called!" <<endl;
}
};
int main( ) {
Box* myBoxArray = new Box[4];
return 0;
}
If you were to allocate an array of four Box objects, the Simple constructor would be called four times
and similarly while deleting these objects, destructor will also be called same number of times.
If we compile and run above code, this would produce the following result:
Constructor called!
Constructor called!
Constructor called!
Constructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Local Classes
A class declared inside a function becomes local to that function and is called Local Class in C++.
For example, in the following program, Test is a local class in fun().
#include<iostream>
using namespace std;
void fun()
{
class Test // local to fun
{
/* members of Test class */
};
}
int main()
{
return 0;
}
#include<iostream>
using namespace std;
void fun()
{
// Local class
class Test
{
/* ... */
};
Test t; // Fine
Test *tp; // Fine
int main()
{
Test t; // Error
Test *tp; // Error
return 0;
}
2) All the methods of Local classes must be defined inside the class only. For example, program 1
works fine and program 2 fails in compilation.
// PROGRAM 1
#include<iostream>
using namespace std;
void fun()
{
class Test // local to fun
{
public:
int main()
{
fun();
return 0;
}
Output:
// PROGRAM 2
#include<iostream>
using namespace std;
void fun()
{
class Test // local to fun
{
public:
void method();
};
int main()
{
return 0;
}
Output:
Compiler Error:
In function 'void fun()':
error: a function-definition is not allowed here before '{' token
3) A Local class cannot contain static data members. It may contain static functions though. For
example, program 1 fails in compilation, but program 2 works fine.
// PROGRAM 1
#include<iostream>
using namespace std;
void fun()
{
class Test // local to fun
{
static int i;
};
}
int main()
{
return 0;
}
Compiler Error:
In function 'void fun()':
error: local class 'class fun()::Test' shall not have static data member 'int fun()::Test::i'
// PROGRAM 2
#include<iostream>
using namespace std;
void fun()
{
class Test // local to fun
{
public:
static void method()
{
cout << "Local Class method() called";
}
};
Test::method();
}
int main()
{
fun();
return 0;
Output:
4) Member methods of local class can only access static and enum variables of the enclosing function.
Non-static variables of the enclosing function are not accessible inside local classes. For example, the
program 1 compiles and runs fine. But, program 2 fails in compilation.
// PROGRAM 1
#include<iostream>
using namespace std;
void fun()
{
static int x;
enum {i = 1, j = 2};
// Local class
class Test
{
public:
void method() {
cout << "x = " << x << endl; // fine as x is static
cout << "i = " << i << endl; // fine as i is enum
}
};
Test t;
t.method();
}
int main()
{
fun();
return 0;
}
Output:
x=0
i=1
// PROGRAM 2
#include<iostream>
using namespace std;
void fun()
{
int x;
// Local class
class Test
{
public:
void method() {
cout << "x = " << x << endl;
}
};
Test t;
t.method();
}
int main()
{
fun();
return 0;
}
Output:
5) Local classes can access global types, variables and functions. Also, local classes can access other
local classes of same function.. For example, following program works fine.
#include<iostream>
using namespace std;
int x;
void fun()
{
class Test1 {
public:
Test1() { cout << "Test1::Test1()" << endl; }
};
Test2 t;
t.method();
}
int main()
{
fun();
return 0;
}
Output:
Test1::Test1()
x=0