C++ Concepts
C++ Concepts
C++ Concepts
Concepts in C++
Angan Adhikari
Concepts in C++
1. Variables and Storage Classes
2. Compilation and Memory Management
3. Object and Classes
4. Pointers and References
5. Inheritance and Composition
6. Constants
7. Statics
8. Functions
9. Operator Overloading
10. Polymorphism and Virtual Functions
11. Multiple Inheritance
12. Dynamic Type Information and Casting
13. Templates
14. Exceptions
15. Standard Template Library (STL)
16. Object Oriented Design Basics
Page 1 of 78
Concepts in C++
auto Æ
- default variable type
- local to a function
static Æ
- retains the values between function calls
- initialized only once
- unavailable outside the scope of the function
extern Æ
- extern keyword tells the compiler that a variable (or function) exists, even if the
compiler has not seen it in the file currently being compiled
- forces external linkage
volatile Æ
- volatile keyword prevents the compiler from performing any optimization based
on the stability of that variable
- value of a volatile variable is always read whenever its value is required
register Æ
- variables are accessed faster
- often placed in register
- address of a register variable cannot be taken or computed i.e. the unary
address-of operator (&) cannot be used with register arrays
- register keyword cannot be used with arrays
Summary Æ
Program (used
Visibility/
Function Function by other file File
Scope
using extern)
Lifetime Function Program Program Program
Initialization
Not initialized 0 0 0
value
Storage stack static memory static memory static memory
Retains value Variables used
Variables used Variables used
when the by several
Purpose by single by several
function functions of
function functions
terminates same file
Linkage No linkage No linkage external internal
Page 2 of 78
Concepts in C++
Page 3 of 78
Concepts in C++
Stack Æ
- all the automatic variables are allocated here
- the size of the stack is limited
- works on Last In First Out (LIFO) mechanism
Linkage Æ
- A name is said to have linkage when it might denote the same object, reference,
function, type, template, namespace or value as a name introduced by a
declaration in another scope.
- When a name has external linkage, the entity it denotes can be referred to by
names from scopes of other translation units or from other scopes of the same
translation unit.
- When a name has internal linkage, the entity it denotes can be referred to by
names from other scopes in the same translation unit.
Page 4 of 78
Concepts in C++
Namespace Æ
- The names of global functions, global variables, and classes are still in a single
global name space. The global name space can be subdivided into more
manageable pieces using the namespace feature of C++.
- An unnamed namespace can be used to make names local to a compilation unit.
The effect of unnamed namespace is very similar to that of the internal linkage.
Example:
namespace
{
class X {};
void f();
int i;
}
Assignment is performed with the operator =. It means “take the right-hand side (often
called the rvalue) and copy it into the left-hand side (often called the lvalue). An rvalue is
any constant, variable, or expression that can produce a value, but an lvalue must be a
distinct, named variable (that is, there must be a physical space in which to store data).
For instance, you can assign a constant value to a variable ( A = 4; ), but you cannot
assign anything to constant value – it cannot be an lvalue (you can’t say 4 = A; ).
Page 5 of 78
Concepts in C++
Constructor Æ
- constructor is used to initialize an object
- Like any member function, the first (secret) argument to the constructor is the
this pointer – the address of the object for which it is being called. In the case of
the constructor, however, this is pointing to an uninitialized block of memory,
and it’s the job of the constructor to initialize this memory properly.
- cannot be called explicitly
- does not return anything
- can be overloaded based on number and type of arguments
- Cannot be virtual
- A pointer to a constructor cannot be had.
Default Constructor Æ
- This constructor can be called without any arguments.
- This is the constructor with no arguments or default argument list.
Example:
Destructor Æ
- Destructor uninitializes an object
- Destructor does not take any arguments and does not return anything, destructor
cannot be overloaded.
- Destructor is called automatically when an automatic object’s scope ends.
Page 6 of 78
Concepts in C++
Singleton class Æ
- A class that assures a maximum of ONE object of its type at a given time and
provides a global access point to this object is a Singleton class.
- Singleton classes may be implemented using a protected constructor and a public
static member of that class itself.
Example:
#include <iostream>
using namespace std;
// Singleton class
class S
{
protected :
S()
{ cout << "Constructing S\n"; }
public :
static S* get_s()
{ return & m_s; }
static Show()
{ cout << "Address of object = " << &m_s << endl; }
};
int main()
{
cout << "main starts" << endl;
S::Show();
S *s1 = S::get_s();
cout << "s1 = " << s1 << endl;
S *s2 = S::get_s();
cout << "s2 = " << s2 << endl;
return 0;
}
Result:
Constructing S
main starts
Address of object = 0047774A
s1 = 0047774A
s2 = 0047774A
Page 7 of 78
Concepts in C++
Example:
#include <iostream>
using namespace std;
class S
{
private:
S()
{ cout << "constructing S.\n"; }
public:
static S* s_method()
{
cout << "static method called.\n";
return new S;
}
};
int main()
{
S *s1 = S::s_method();
S *s2 = S::s_method();
return 0;
}
Result:
static method called.
constructing S.
static method called.
constructing S.
s1 = 00301FF0
s2 = 00301FC0
Page 8 of 78
Concepts in C++
Example :
#include <iostream>
using namespace std;
class c1
{
public:
int val;
c1(int i) {val = i;}
int double_val() {return (val + val);}
};
int main()
{
int c1::*data; // data member pointer
int (c1::*func) (); // function member pointer
c1 ob(5);
c1 *pob = &ob;
return 0;
}
Result:
value = 5
Page 9 of 78
Concepts in C++
double value = 10
value = 5
double value = 10
Dangling Pointers Æ
- A pointer points to a heap-dynamic variable that has been de-allocated
Example:
#include <iostream>
using namespace std;
int main()
{
int *p;
p = new int(10);
return 0;
}
Memory leak Æ
- A memory leak occurs when all pointers to a block of allocated memory have
been lost.
- Leaked memory cannot be accessed or reallocated
- Excessive memory leaks may cause the program to crash
Example:
#include <iostream>
using namespace std;
int main()
{
int *p;
p = new int(10);
p = new int(20);
// pointer to memory having integer value 10 is lost – memory leak
Page 10 of 78
Concepts in C++
return 0;
}
Segmentation fault Æ
- Segmentation fault occurs when there is an invalid pointer de-referencing.
"Invalid pointer" can be a NULL pointer, an un-initialized pointer, or a pointer
pointing to a piece of de-allocated memory. When you de-reference it by, say,
*ptr or by ptr->next, segmentation occurs.
new Æ
- new operator has similar functionality as malloc() in C. It performs three tasks:
1. Allocates memory for the object from the heap or free store.
2. Returns a pointer to an appropriate data type.
3. Calls the constructor for the object.
delete Æ
- Memory that is dynamically allocated using the new operator can be freed using
the delete operator. It performs two tasks:
1. Calls the destructor for the object
2. De-allocates memory back to free store
- operator delete cannot return a value
- To de-allocate dynamically allocated arrays the delete operator should be
followed by []
Example:
int *pt = new int[1024]; // allocates an array of 1024 integers
delete[] pt; // deletes the dynamic array
Syntax:
X *px = ::new X();
::delete px;
Example:
Page 11 of 78
Concepts in C++
class X
{
int i;
public:
X(int ii = 0) : i(ii)
{
cout << "X::X() : this = " << this << endl;
// throw "some_exception";
// placement delete is called when exception is thrown
}
~X()
{ cout << "X::~X() : this = " << this << endl; }
int main()
{
int a[10];
cout << "a = " << a << endl;
try
{
X* px = new(a) X(50); // Place X at location a
px->X::~X(); // Explicit destructor call
}
catch (const char * some_string)
{
cout << "catch : " << some_string << endl;
}
return 0;
}
Page 12 of 78
Concepts in C++
Example:
- A const reference can refer to a const int. It is done with a temporary variable
with value of the const and then the initialization of reference with that variable.
This temporary variable persists until the end of its reference’s scope.
- Array of references cannot be created as each reference in the array cannot be
initialized at the time of creation.
- A pointer can point to many different objects during its lifetime; a reference can
refer to only one object during its lifetime i.e. a reference cannot be rebound.
- References, unlike pointers, have to be initialized at the point of definition
Page 13 of 78
Concepts in C++
// Sample 1
int* p;
...
int& r = *p; // reference r is bound to the object p points to – can be NULL
// Sample 2
int& f() // function f returns a reference to integer i
{
int i;
...
return i; // storage of i vanishes as the function returns
}
Example:
#include<iostream>
using namespace std;
int main()
{
int i = 10;
int &ri = i;
return 0;
}
Result:
&i = 0x7f7f06a8
ri = 10
&ri = 0x7f7f06a8
Page 14 of 78
Concepts in C++
Example:
#include <iostream>
#include <string>
using namespace std;
class C
{
public:
int m,n;
C(): m(1),n(2) {}
void show() const
{
cout << "m = " << m << endl;
cout << "n = " << n << endl << endl;;
}
};
int main()
Page 15 of 78
Concepts in C++
{
C x;
int *p = &(x.m);
int *q = &(x.n);
x.show();
return 0;
}
Result:
m=1
n=2
m=2
n=1
m=1
n=2
m=2
n=1
m=1
n=2
m=1
n=2
Page 16 of 78
Concepts in C++
Public Inheritance Æ
- Normally the inheritance is done as public so that interface of the base class is
also an interface of the derived class.
Private Inheritance Æ
- In private inheritance all the data member and functionality of the base class is
hidden
- To make the public members of the base class visible in the derived class the
names of those members have to be specified in the public section of the derived
class without any arguments or return values
Example:
#include <iostream>
using namespace std;
class B
{
public:
char f1() const { return 'a'; }
int f2() const { return 2; }
float f3() const { return 3.0; }
float f3(int) const { return 4.0; }
};
Page 17 of 78
Concepts in C++
};
int main()
{
D d;
d.f1();
// d.f2(); // Error: private member function
d.f3();
d.f3(1);
return 0;
}
Protected Inheritance Æ
- Protected inheritance is done to make the base class interface available to
derived classes and friends
Pointer Æ
- The pointer to a base class can contain the address of a derived class object
- The pointer to a derived class cannot contain the address of a base class object
Page 18 of 78
Concepts in C++
- destructors for derived classes should not worry about clean up related to
inherited properties
- destructor of base class is automatically called after the destructor of derived
class.
Name Hiding Æ
- When a class is inherited and one member function is given a new definition,
there are two possibilities
- Anytime a function is given a new definition in the derived class, all the other
versions are automatically hidden in the new class
- Overloading is not possible across scopes
Example:
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
int f()
{ cout << "Base::f()\n";
return 1;
}
void g(){}
};
Page 19 of 78
Concepts in C++
}
};
int main()
{
string s("C++");
Derived1 d1;
int x = d1.f();
d1.f(s);
Derived2 d2;
x = d2.f();
//d2.f(s); // Error: string version hidden
Derived3 d3;
d3.f();
//x = d3.f(); // Error: return int version hidden
Derived4 d4;
//x = d4.f(); // Error: f() version hidden
x = d4.f(1);
return 0;
}
Result:
Base::f()
Derived2::f()
Derived3::f()
Derived4::f()
Finalizing a class Æ
- This is a way of preventing any other inheritance from a particular class.
- It relies on the fact that the most derived class in a hierarchy must construct a
virtual base
Page 20 of 78
Concepts in C++
Example:
#include <iostream>
using namespace std;
int main()
{
Usable u1; // ok
return efficiency
When new objects are created to return by value, notice the form used. In
operator+, for example:
This may look at first like a “function call to a constructor,” but it’s not. The
syntax is that of a temporary object; the statement says “make a temporary
Integer object and return it.” Because of this, you might think that the result
is the same as creating a named local object and returning that. However, it’s
quite different. If you were to say instead:
Page 21 of 78
Concepts in C++
return tmp;
three things will happen. First, the tmp object is created including its
constructor call. Then, the copy-constructor copies the tmp to the location of
the outside return value. Finally, the destructor is called for tmp at the end
of the scope.
Page 22 of 78
Concepts in C++
Constants
Const correctness Æ
- the keyword const provides features that can help you create more robust and
bug-free applications. This is called const correctness
Constant folding Æ
- This is the replacement of the const variable with its value (if available at compile
time) by the compiler wherever it is found in the file
- The difference between the macro (#define) and constant folding is the former
is replaced by value by the preprocessor and the later is done by compiler –
hence type checking is done here.
Example:
Here the constant folding cannot take place at compile time but the code compiles
without any errors.
Linkage Æ
- C defaults to external linkage of const and storage is always created
- C++ defaults to internal linkage of const and does not necessarily create
storage. When defined as extern the storage is created for const
- In C++ the const that is outside all functions has got a file scope
extern const int x; // declaration: does not allocate storage and constant
// folding cannot take place within the file as it does not
// know the value
Example:
char *str = “California”;
const char *str = “California”; // same effect
const in Aggregates Æ
- Storage is allocated for constant aggregates
- the value cannot be used at compile time because the compiler is not required to
know the contents of the storage at compile time.
Example:
Page 23 of 78
Concepts in C++
int main()
{
int p; // p is initialized to some garbage value
int c[p]; // ok:
return 0;
}
Example:
void func(const int a)
{
// a++; // Illegal
}
Example:
#include <iostream>
using namespace std;
int main()
{
const int j = f3(); // Works fine
Page 24 of 78
Concepts in C++
return 0;
}
Example:
class X
{
int i;
public:
X(int ii = 0);
void modify();
};
int main()
{
f5() = X(1); // ok – but not recommended - probably a bug
f5().modify(); // ok – but not recommended - probably a bug
f7(f5()); // ok
// f6() = X(1); // Error: reassignment of constant
// f6().modify(); // Error: modification of constant object
// f7(f6()); // Error: f7() does not take const reference
return 0;
}
Page 25 of 78
Concepts in C++
argument by const reference, it has permission to modify the temporary object. But
the compiler knows that the temporary will vanish as soon as the expression
evaluation is complete, and thus any modifications you make to the temporary X will
be lost. By making all temporary objects automatically const, this situation
causes a compile-time error.
Example:
int main()
{
int x = 0;
int* ip = &x;
const int* cip = &x;
t(ip); // ok
// t(cip); // Error
u(ip); // ok
u(cip); // ok
// char* cp = v(); // Error
const char* ccp = v(); // ok
// int* ip2 = w(); // Error
const int* const ccip = w(); // ok
const int* cip2 = w(); // ok
// *w() = 1; // Error
return 0;
}
Page 26 of 78
Concepts in C++
Example:
class X {};
int main()
{
// g1(f()); // Error: const temporary created by f():
g2(f()); // ok - g2 takes a const reference
return 0;
}
Pointer to const Æ
const int * u; // u is a pointer that points to constant int
int const * v; // v is a pointer that points to constant int
const pointerÆ
int d = 1; // declare integer
int * const w = &d; // w is a constant pointer to an int
Note: -
1. Constant pointer to an integer takes assignment of int pointer as well as
constant integer pointer.
2. To allow temporaries to be passed to functions by reference, the argument
must be a const reference.
Page 27 of 78
Concepts in C++
Example:
#include <iostream>
using namespace std;
class A
{
const int i;
// const int i = 5; // Error: initialization not possible
public:
A(int x):i(x){}
};
int main()
{
A a(5);
return 0;
}
Example:
#include <iostream>
using namespace std;
class C
{
static const int a = 1024;
enum{ b = 19 };
Page 28 of 78
Concepts in C++
Syntax:
int func(int a) const
{ ..... }
Constant objects Æ
- No data members of the object are changed during the lifetime of the object
- When a member is declared as constant the compiler is told that it will be called
for constant objects
- A non constant member function is treated as one that will modify data members
in an object, and the compiler does not allow to call that non constant function
for a constant object.
mutable Æ
- Mutable is a C++ keyword that specifies that a member may be updated or
modified even if it is a member of a const object. The constant member functions
can change mutable members.
Example:
#include <iostream>
using namespace std;
class Animal
{
private:
mutable int age; // mutable member
public:
Animal(int a) {age = a;}
void setAge(int newage) const {age = newage;}
};
int main()
{
const Animal Tiger(3); // constant object
Tiger.setAge(4);
return 0;
}
Note:-If you declare a member function const, you tell the compiler the function
can be called for a const object. A member function that is not specifically
declared const is treated as one that will modify data members in an object, and
the compiler will not allow you to call it for a const object
explicit Æ
- This keyword is a declaration specifier that can only be applied to in-class
constructor declarations.
- Constructors declared explicit will not be considered for implicit conversions.
- It is meaningless to apply explicit to constructors with multiple arguments, since
such constructors cannot take part in implicit conversions.
Page 29 of 78
Concepts in C++
Example:
#include <iostream>
using namespace std;
class X
{
public:
explicit X(int) // explicit constructor
{ cout << "X::X() called.\n" ; }
};
class Y
{
public:
Y(int)
{ cout << "Y::Y() called.\n" ; }
};
void f1(X)
{ cout << "f(X) called.\n" ; }
void f2(Y)
{ cout << "f(Y) called.\n" ; }
int main()
{
int i = 10;
return 0;
}
Result:
Y::Y() called.
f(Y) called.
Page 30 of 78
Concepts in C++
6. Statics
Example:
#include <iostream>
using namespace std;
class A
{
static int i; // declaration
static int j; // declaration
};
Syntax:
someclass :: some_static_function();
Page 31 of 78
Concepts in C++
Static objects Æ
- The static objects of user-defined types must be initialized with constructor calls.
i.e. either with default constructors or with constructor argument list
- Static objects within function are initialized when the control passes through the
definition for the first time.
- The constructor for a global static object is called before main() is entered
- The static objects (both local and global) are destroyed when the main()
terminates. The destructors are called in a reverse order.
Example:
#include <iostream>
using namespace std;
class X
{
char c;
public:
X(char cc = 'a') : c(cc) // Default Constructor
{ cout << "X::X() for " << c << endl; }
~X() // Destructor
{ cout << "X::~X() for " << c << endl; }
};
void f()
{
cout << "Called f()" << endl;
static X x1('b');
static X x2; // Default constructor required
cout << "Returning from f()" << endl;
}
int main()
{
cout << "main() starts" << endl;
f();
cout << "main() ends" << endl;
return 0;
}
Result:
X::X() for c
main() starts
Called f()
X::X() for b
X::X() for a
Returning from f()
main() ends
X::~X() for a
Page 32 of 78
Concepts in C++
X::~X() for b
X::~X() for c
Named Constructor Æ
- With the Named Constructor Idiom, all the class's constructors are declared in
the private or protected sections, and public static methods are provided that
return an object. These static methods are the so-called "Named Constructors."
In general there is one such static method for each different way to construct an
object.
Example:
#include <stdio.h>
class Point
{
public:
static Point rectangular(float x, float y); // Rectangular coord's
static Point polar(float radius, float angle); // Polar coordinates
// These static methods are the so-called "named constructors"
private:
Point(float x, float y); // Rectangular coordinates
float x_, y_;
};
int main()
{
Point p1 = Point::rectangular(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5.7, 1.2); // Obviously polar
return 0;
}
Example:
Page 33 of 78
Concepts in C++
#include <iostream>
using namespace std;
class Outer
{
class Inner
{
static int i; // declaration
};
};
void f()
{
class Local
{
public:
// static int i; // Error : definition is impossible
} x;
}
int main()
{
Outer x;
f();
return 0;
}
Page 34 of 78
Concepts in C++
7. Functions
Function call Æ
- During a function call the followings are pushed into the stack in the following
order and popped from the stack in the reverse order
1. function arguments from right to left
2. return address
3. local variables
Function Pointers Æ
- function pointer contains address of a function
Example:
#include <iostream>
using namespace std;
int main()
{
void (*fp)(); // Define a function pointer
fp = func; // Initialize it
(*fp)(); // Dereferencing calls the function
return 0;
}
Result:
func() called
func() called
Page 35 of 78
Concepts in C++
Function overloading Æ
- A function can be overloaded on the number of arguments and the type of the
arguments within the same scope.
- A function cannot be overloaded on the return type only, as it is not mandatory
to take the return value of a function.
Example:
- To avoid name mangling for C functions (from a C Library) used in C++ code the
compiler can told explicitly to perform the C Linkage (without mangling) using
extern keyword.
Example:
extern "C" float f(int a, char b); // C Linkage without name mangling
Inline function Æ
- C++ implements macro as inline function
- Function definition inside a class definition is automatically inline
- Inline function is expanded in place, like a preprocessor macro so that overhead
of function call is eliminated
- The keyword inline is just a suggestion to the compiler to make the function
inline. There are cases when the inilining cannot be performed:
1. Compiler cannot perform inlining if the function is too complicated
2. Compiler cannot perform inlining if the addess of the function is taken
implicitly or explicitly. If the compiler must produce an address, then it will
allocate storage for the function and use the resulting address.
3. Compiler does not perform inlining if are static variables used in the function
Page 36 of 78
Concepts in C++
Default arguments Æ
- default arguments are provided in the function declaration
- functions declared with default arguments can be called without any parameters
Syntax:
void func(int i=5, char c=’A’);
Friend function Æ
- these functions can operate on objects of two different classes and can access
private data members of both
- classes can also be friends
- friendship is not inherited
- friend functions are not members of a class.
- friend functions do not have this pointer.
Copy constructor Æ
- This is provided automatically by the compiler for every object
- copy constructor creates a new object and performs a member by member copy
- the difference between copy constructor and assignment operator is that copy
constructor creates a new object
- in the copy constructor the argument must be passed by reference X(const X&),
which creates no copies. Otherwise, the copy constructor calls itself and the
compiler runs out of memory.
- The copy constructor is invoked when an object is passed by value to a function
- The copy constructor is invoked when a value is returned from a function
- To avoid copying the copy constructor and the assignment operator can be
overloaded as private members
- both the statements
Example:
#include <iostream>
using namespace std;
class X
{
Page 37 of 78
Concepts in C++
public:
X() // Constructor
{ cout << "X::X()" << endl; }
X f1()
{
cout << "f1()" << endl;
X x;
return x;
}
X f2()
{
cout << "f2()" << endl;
return X();
}
int main()
{
f1();
cout << endl;
f2();
return 0;
}
f2()
X::X()
Page 38 of 78
Concepts in C++
- A deep copy copies all fields, and makes copies of dynamically allocated memory
pointed to by the fields
- A class that requires deep copies will generally need:
• An overloaded copy constructor to make a copy of the dynamically allocated
memory.
• An overloaded assignment operator to make a copy of the dynamically
allocated memory.
• A destructor to delete the dynamically allocated memory
Will
Is Function Can Compiler
Can Is Function
Function Inherited Function Generate
Function Be a Member
Type from Base Return a Function if
Virtual? or Friend?
Class? Value? User Does
Not?
Copy
No No No Member Yes
Constructor
Assignment
No Yes Yes Member Yes
(operator =)
operator Static
Yes No void* No
new member
Page 39 of 78
Concepts in C++
operator Static
Yes No void No
delete member
Other
member Yes Yes Yes Member No
functions
Friend
No No Yes Friend No
functions
Page 40 of 78
Concepts in C++
7. Operator Overloading
Operator Functions Æ
- Functions defining meanings for the following operators can be declared
+ - * / % ^ &
| ~ ! = < > +=
-= *= /= %= ^= &= |=
<< >> >>= <<= == != <=
>= && || ++ -- ->* ,
-> [] () new new[] delete delete[]
- ?: (conditional operator)
- sizeof (sizeof operator)
- typeid (type identification operator)
The general reason for this restriction is safety. If these operators are overloaded the
safety mechanism may be broken and existing practice may become confusing.
Page 41 of 78
Concepts in C++
assignment operator = Æ
- Operator = must be a non-static member of a class. It does not get inherited.
- Every class has a default operator =, unless it is redefined by the class. The
default operator is defined as member wise assignment of each member of the
class. The definition is
X& operator = (const X&)
- Assignment operator resembles constructors and destructors more than in
resembles operators such as += or ++.
- When the default assignment operator (provided by compiler) of a derived class
is invoked, the assignment operator of the base class if defined is called
implicitly.
- If the base class assignment operator is not defined then the default assignment
operator is called.
Example:
#include <iostream>
using namespace std;
class B
{
public:
B& operator =(const B&) // overloaded assignment operator
{ cout << "B::=()" << endl; }
};
class D1 : public B
{
public:
D1& operator =(const D1&) // overloaded assignment operator
{ cout << "D1::=()" << endl; }
};
class D2 : public B
{
};
int main()
{
B b1, b2;
D1 x1, x2;
D2 y1, y2;
b1 = b2;
x1 = x2;
y1 = y2;
b1 = x1;
b1 = y1;
// x1 = b1; // Error
// x1 = y1; // Error
// y1 = x1; // Error
Page 42 of 78
Concepts in C++
// y1 = b1; // Error
return 0;
}
Result:
B::=()
D1::=()
B::=()
B::=()
B::=()
Example:
class X
{
public:
operator ++();
};
void f(X a)
{
++a; // a.operator++()
}
Example:
class X
{
public:
operator ++ (int);
};
void f(X a)
{
a++ ; // a.operator ++ (0);
}
Page 43 of 78
Concepts in C++
Example:
#include <iostream>
using namespace std;
class X
{
public:
int j;
};
void user(int k)
{
Smart_Ptr<X> spx(k);
spx->j = k;
cout << "spx->j = " << spx->j << endl;
}
int main()
{
user(23);
return 0;
}
Result:
overloaded operator ->
overloaded operator ->
spx->j = 23
Page 44 of 78
Concepts in C++
Example:
char * Æ string
use constructor taking built-in type as argument – implicit conversion
Example:
string Æ char *
operator char*()
{
objA = objB
// where objB is source type and objA is destination type.
Case 1:
Overloaded casting operator is defined in source class which return destination class
Case 2:
Constructor of destination class takes source type as argument, converts destination
class type to source type.
Example:
#include <iostream>
using namespace std;
class B;
/*
A(B temp_b) // destination class constructor
// taking source object and assigning
Page 45 of 78
Concepts in C++
{
cout << "Conversion constructor called" << endl;
a = temp_b.get();
}
*/
};
int main()
{
A objA(1);
B objB(2);
objA = objB;
cout << "objA::a = " << objA.get() << endl;;
return 0;
}
Result:
Overloaded casting operator function
objA::a = 2
Page 46 of 78
Concepts in C++
Virtual Function Æ
- Keyword virtual tells the compiler to enforce late binding of the function when the
address of the base class is used
- The inhertance from the base class to the derived class must be public
- A call to a virtual function is resolved according to the underlying type of object
for which it is called.
- A call to a non-virtual function is resolved according to the type of the pointer or
reference.
- If a function is declared virtual in the base class it is virtual in all derived classes
throghout the inhertance hierarchy.
- Virtual function must be member of some class
- Virtual function cannot be a static member function or a global function
- A virtual function that has been defined in a base class need not be defined in the
derived class. If it is not, the function defined for the base is called
- It is an error for a derived class function to differ from a base class virtual
function in the return type only.
- If return type is same and argument list differ, compiler allows this but late
binding is not happen.
Example:
#include <iostream>
using namespace std;
};
Page 47 of 78
Concepts in C++
void f3()
{ cout << "Called Derived::f3()\n"; }
};
int main()
{
Base *bp = new Derived;
bp->f1();
bp->f2();
// bp->f3(); // Error: Base::f3 not available
Result:
Called Derived::f1()
Called Base::f2()
Size of Derived = 4 (VPTR)
Function Overriding Æ
- The redefinition of a virtual member function in a derived class with the same
signature is called function overriding
Page 48 of 78
Concepts in C++
- The use of one or more pure virtual function makes a class abstract, which
means that no object can be instantiated from it.
- When an abstract class is inherited, all the pure virtual functions must be
implemented, or the inherited class becomes abstract as well.
Syntax:
virtual void pure_virtual_func() = 0;
Object Slicing Æ
- Passing a derived object by value to a function that takes a base object by value
may cause a problem known as "object slicing"; every additional member
declared in the derived object is omitted. The resultant object contains only the
members declared in the base class.
- Dynamic binding mechanism is inoperative in this case.
Example:
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f1() // virtual member function
{ cout << "Base::f1()" << endl; }
void func1(Base b)
{
b.f1(); // No dynamic binding - calls Base:f1()
b.f2();
// b.f3(); // Error : f3 not available - sliced
}
Page 49 of 78
Concepts in C++
bp->f1();
bp->f2();
// bp->f3(); // Error : f3 not available
}
int main()
{
Base b;
Derived d;
func1(d);
func2(&d);
return 0;
}
Result:
Size of Base = 4
Size of Derived = 4
Base::f1()
Base::f2()
Derived::f1()
Base::f2()
Example:
#include <iostream>
using namespace std;
};
Page 50 of 78
Concepts in C++
~Derived () // Destructor
{ cout << "Called Derived::~Derived()\n"; }
};
int main()
{
Base *bp = new Derived;
delete bp;
return 0;
}
Result:
Called Base::Base()
Called Derived::Derived()
Called Derived::~Derived()
Called Base::~Base()
Example:
#include <iostream>
using namespace std;
Page 51 of 78
Concepts in C++
};
~Derived() // destructor
{ cout << "Derived::~Derived()\n";
f1();
f2();
}
int main()
{
Base * bp = new Derived;
cout << "\nAfter construction\n\n";
delete bp;
return 0;
}
Result:
Base::Base()
Base::f1()
Base::f2()
Derived::Derived()
Derived::f1()
Derived::f2()
Page 52 of 78
Concepts in C++
After construction
Derived::~Derived()
Derived::f1()
Derived::f2()
Base::~Base()
Base::f1()
Base::f2()
Factory pattern Æ
- Factory pattern is a technique for generating an object of an appropriate type
using an abstract class.
Example:
#include <iostream>
using namespace std;
class A
{
// …
};
class AX : public A
{
// …
};
class FX : public F
{
Page 53 of 78
Concepts in C++
public:
A* make_an_A() const // override
{ return new AX(); }
};
int main()
{
user(FX()); // this user makes AXs
return 0;
}
Page 54 of 78
Concepts in C++
9. Multiple Inheritance
Example:
#include <iostream>
using namespace std;
class Base
{
int k;
public:
virtual char* vf() const = 0; // pure virtual function
virtual ~Base() {}
};
Page 55 of 78
Concepts in C++
int main()
{
Base* bp[3];
return 0;
}
Result:
D1
D2
Example:
#include <iostream>
using namespace std;
class Base
{
int k;
public:
virtual char* vf() const = 0; // pure virtual function
virtual ~Base() {}
};
Page 56 of 78
Concepts in C++
{
public:
char* vf() const { return "VMI"; }
};
int main()
{
Base* bp[3];
return 0;
}
Result:
VD1
VD2
VMI
Overhead Æ
- The multiple inheritance mechanism is implemented using pointers
- The classes bear the extra overhead of pointers
Example:
#include <iostream>
using namespace std;
class Base
{
int k;
public:
virtual char* vf() const{};
virtual ~Base() {}
};
Page 57 of 78
Concepts in C++
int main()
{
Base b;
D1 d1;
MI mi;
VD1 vd1;
VMI vmi;
Page 58 of 78
Concepts in C++
return 0;
}
Result:
size of b = 8 (int + VPTR)
size of d1 = 8 (int + VPTR)
size of mi = 16 (int + VPTR + int + VPTR)
size of vd1 = 12 (int + VPTR + Extra pointer)
size of vmi = 16 (int + VPTR + VPTR + Extra pointer)
Page 59 of 78
Concepts in C++
typeid Æ
- information about unknown object can be found with this operator
dynamic_cast Æ
- type of a class can be checked with this operator
- type safe downcasting is done with this
- pointer types can be changed with this operator
Example:
Base *bp;
Derived d;
Bp = &d;
dp = dynamic_cast<Derived *>(bp);
const_cast Æ
- this operator is used to explicitly override const/volatile in a cast
static_cast Æ
- performs a non polymorphic cast
- can be used for any standard conversion
reinterpret_cast Æ
- this converts one type into a fundamentally different type. eg. pointer into an
integer
Page 60 of 78
Concepts in C++
11. Templates
Advantages of templates Æ
- code reuse
- allows container classes (e.g. lists, arrays, etc.) to be simply defined without loss
of static type checking or run-time efficiency.
- allows definition of generic functions (e.g., sort) to be defined once for a family of
types
auto_ptr Æ
- Auto_ptr is a template class and is initialized with a pointer and can be
derefenced in the way a pointer can.
- Auto_ptr supports resource acquisition is initialization technique
- Auto_ptr has ownership semantics or destructive copy semantics – when an
auto_ptr is copied into another, the source no longer points to anything
- Copying a auto_ptr modifies it – a const auto_ptr cannot be copied.
- The purpose of the auto_ptr scheme is that dynamically allocated objects are
properly destroyed in all circumstances i.e. the object’s destructor is properly
executed.
- Template specification of auto_ptr:
template<class T>
class auto_ptr
{
public:
typedef T element_type;
~auto_ptr();
Page 61 of 78
Concepts in C++
Example:
#include <iostream>
#include <memory>
using namespace std;
class X
{
public:
X() { cout << “X::X()\n” ;}
~X() { cout << “X::~X()\n” ;}
void f() { cout << “X::f()\n”; }
};
int main()
{
auto_ptr<X> p1(new X), p2;
X *ptr = p2.get();
ptr ->f();
return 0;
}
Result:
X::X()
X::f()
X::f()
X::~X() (Destructor called when scope ends)
Page 62 of 78
Concepts in C++
12. Exceptions
Page 63 of 78
Concepts in C++
typedef void
(*unexpected_function)();
Install your own termination
set_unexpected function to be called by
unexpected_function
unexpected
set_unexpected(
unexpected_function unexp_func);
Called automatically under
void terminate(void); certain circumstances after
exception is thrown. The
terminate
terminate_function set_terminate( terminate function calls
terminate_function term_fun ); abort() or a function you
specify using set_terminate
Calls terminate() or a
unexpected void unexpected(void); function you specify using
set_unexpected.
Page 64 of 78
Concepts in C++
Example:
#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;
void custom_handler()
{
cout << "Inside custom_handler" << endl;
abort();
}
int main()
{
cout << “main starts” << endl;
set_terminate(custom_handler); // set new terminate handler
try
{
cout << "Inside try block" << endl;
throw 100; // throw integer exception
}
catch (double i) // does not catch int exception
{
cout << "Inside catch" << endl;
}
Result:
main starts
Inside try block
Inside custom_handler
abnormal program termination
Page 65 of 78
Concepts in C++
Rethrow an exception Æ
- When an exception is rethrown, it is not re-caught by the same catch statement.
It propagates outwards to the next catch statement.
Example:
#include <iostream>
using namespace std;
void Xhandler()
{
try
{
throw "Hello";
}
catch (const char* str)
{
cout << "Caught " << str << " inside Xhandler” << endl;
throw; // rethrow exception
}
}
int main()
{
cout << "main starts" << endl;
try
{
Xhandler();
}
catch (const char* str)
{
cout << "Caught " << str << " inside main" << endl;
}
Result:
main starts
Caught Hello inside Xhandler
Caught Hello inside main
main ends
Page 66 of 78
Concepts in C++
Components of STL Æ
- Containers
- Iterators
- Algorithms
- Predicates or Function Objects
- Allocators
Containers Æ
- Container is an object that stores data in a certain way in memory
- Implemented using template classes and hence can hold any type of data
- classified in to 3 types
1. Sequence Containers (vector, list, deque)
2. Associative Containers (set, multiset, map, multimap)
3. Derived containers or container adapters (stack, queue, priority_queue)
Sequence Containers Æ
Associative Containers Æ
Page 67 of 78
Concepts in C++
Iterators Æ
Page 68 of 78
Concepts in C++
Iterator Read/
Access Direction Description
Type Write
linear forward only R - Read an element.
- Move only one element at a
Input
time.
- Supports one-pass algorithms
linear forward only W - Write an element.
- Move only one element at a
output
time.
- Supports one-pass algorithms
linear forward only RW - Have the capabilities of input &
forward output iterators.
- Can retain the current state
linear forward & RW - Has forward iteration capability
back and can move in both
bidirectional
directions.
- Supports Multi-pass algorithms
random forward & RW - Has bi-directional capability
random back and can access any element &
access move arbitrary no. of elements
Algorithms Æ
- operate on containers
- can be applied on ordinary C++ arrays
Important Algorithms Æ
Algorithm Description
looks for the first element in a container that has a specified value
find()
counts the number of elements in acontainer having a specified
count()
value and returns this number
sorts the elements in a container
sort()
looks for a sequence of values , specified by one container, within
search()
another container
works on three containers, merging the elements from two source
merge()
containers into a destination container
Page 69 of 78
Concepts in C++
Example:
#include <iostream>
#include <vector>
using namespace std;
#include <algo.h>
class multiply
{
public:
int operator()(int x, int y) // overloaded () operator
{ return x*y; }
};
int main()
{
int x[5] = {1, 2, 3, 4, 5};
vector<int> v1(x, x+5); // initialize vector
return 0;
}
Result:
product = 120
Allocators Æ
- Every STL container class defines an allocator class that manages the allocation
of memory for the container.
- STL provides default allocator object for each container types so that
programmers need not deal with it directly.
Page 70 of 78
Concepts in C++
- STL uses this allocator for storage allocation instead of using new and delete
- Programmers can supply allocator to customize how a container handles storage
management
Page 71 of 78
Concepts in C++
ISA Relationship Æ
- A specialized class "is" a specialization of another class and, therefore, has the
ISA relationship with the other class.
- This relationship is best implemented by
• deriving one class from another - inheritance
Example:
An Employee ISA Person. Employee is derived from Person.
HASA Relationship Æ
- A class may have an instance of another class.
- This relationship can be implemented in two ways:
• Embedding one class object in another - composition
• Having one class as an inner class of the other – inner class
Example:
An employee "has" a salary, therefore the Employee class has the HASA relationship
with the Salary class. This relationship is best implemented by embedding an object
of the Salary class in the Employee class.
15. Anonymous
Anonymous Unions
Anonymous unions are unions that are declared without a class-name or declarator-
list.
Syntax
union { member-list } ;
Such union declarations do not declare types — they declare objects. The names
declared in an anonymous union cannot conflict with other names declared in the
same scope.
Names declared in an anonymous union are used directly, like nonmember variables.
The following example illustrates this:
#include <iostream.h>
struct DataForm
{
enum DataType { CharData = 1, IntData, StringData };
DataType type;
Page 72 of 78
Concepts in C++
char chCharMem;
char *szStrMem;
int iIntMem;
};
void print();
};
void DataForm::print()
{
// Based on the type of the data, print the
// appropriate data type.
switch( type )
{
case CharData:
cout << chCharMem;
break;
case IntData:
cout << szStrMem;
break;
case StringData:
cout << iIntMem;
break;
}
}
In the function DataForm::print, the three members (chCharMem, szStrMem, and
iIntMem) are accessed as though they were declared as members (without the
union declaration). However, the three union members share the same memory.
In addition to the restrictions listed in Union Member Data, anonymous unions are
subject to additional restrictions:
• They can have only public members; private and protected members in
anonymous unions generate errors.
Note Simply omitting the class-name portion of the syntax does not make a union
an anonymous union. For a union to qualify as an anonymous union, the declaration
must not declare an object.
Anonymous Structures
Anonymous structures can be useful when the tag named is not needed. This is the
case when one declaration defines all structure instances. For example:
struct
{
int x;
int y;
Page 73 of 78
Concepts in C++
} mystruct;
Embedded structures are often anonymous.
struct somestruct
{
struct /* Anonymous structure */
{
int x, y;
} point;
int type;
} w;
static_cast
A static_cast is used for all conversions that are well-defined. These include
“safe” conversions that the compiler would allow you to do without a cast and
less-safe conversions that are nonetheless well-defined. The types of
conversions covered by static_cast include typical castless conversions,
narrowing (information-losing) conversions, forcing a conversion from a void*,
implicit type conversions, and static navigation of class hierarchies:
//: C24:Statcast.cpp
// Examples of static_cast
Page 74 of 78
Concepts in C++
void func(int) {}
int main() {
int i = 0x7fff; // Max pos value = 32767
long l;
float f;
// (1) typical castless conversions:
l = i;
f = i;
// Also works:
l = static_cast<long>(i);
f = static_cast<float>(i);
Page 75 of 78
Concepts in C++
int main() {
const int i = 0;
int* j = (int*)&i; // Deprecated form
j = const_cast<int*>(&i); // Preferred
// Can't do simultaneous additional casting:
//! long* l = const_cast<long*>(&i); // Error
volatile int k = 0;
int* u = const_cast<int*>(&k);
}
class X {
Page 76 of 78
Concepts in C++
int i;
// mutable int i; // A better approach
public:
void f() const {
// Casting away const-ness:
(const_cast<X*>(this))->i = 1;
}
}; ///:~
If you take the address of a const object, you produce a pointer to a const, and
this cannot be assigned to a non const pointer without a cast. The old-style cast
will accomplish this, but the const_cast is the appropriate one to use. The same
holds true for volatile.
If you want to change a class member inside a const member function, the
traditional approach is to cast away constness by saying (X*)this. You can still
cast away constness using the better const_cast, but a superior approach is to
make that particular data member mutable, so it’s clear in the class definition,
and not hidden away in the member function definitions, that the member may
change in a const member function.
Questions:
Page 77 of 78
Concepts in C++
A) not thread safe. Use mutex lock before creating the objects.
13) What is design a pattern?
A)
14) What are different types of design pattern ?
A)
15) What is a visitor design pattern ?
A)
16) How many argument can be passed to a c-function as per ANSI standard ?
A) 253
17) Why do you pass arguments by reference in copy constructor? And what
happen if it is passed by value?
A) by value, it will be out of memory because of infinite loop. But in case of
reference, no copy constructor is being called.
18) In what all scenarios copy constructor is being called ?
A) retun statement, passing argument.
19) What is a private inheritace ? and why it is used ?
A) All the public and protected members become private in derived class.
B) To avoid the bottom to top casting.
20) How to overload ++A and A++ operated in user defined data type and how
compiler distinguish it ?
A) in A++ overloading you will pass an argument….you may refer some study
material….
21) What s/f life cycle you have used?????
22) what are different life cycles and their advantages….
Page 78 of 78