You are on page 1of 24

C++ Examples

TCS Internal July 5, 2011

Stack vs. Heap


When a program is loaded into memory, it is organized into three areas of memory, called segments: the text segment, stack segment, and heap segment.

The text segment (sometimes also called the code segment) is where the compiled code of the program itself resides. This is the machine language representation of the program steps to be carried out, including all functions making up the program, both user and system defined.

When a program begins executing in the function main(), space is allocated on the stack for all variables declared within main(). If main() calls a function, func1(), additional storage is allocated for the variables in func1() at the top of the stack. The parameters passed by main() to func1() are also stored on the stack. If func1() were to call any additional functions, storage would be allocated at the new Top of stack. When func1() returns, storage for its local variables is deallocated. If main() were to call another function, storage would be allocated for that function at the Top. Thus, the memory allocated in the stack area is used and reused during program execution. Memory allocated in this area will contain garbage values left over from previous usage.

The heap segment provides more stable storage of data for a program; memory allocated in the heap remains in existence for the duration of a program. Therefore, global variables (storage class external), and static variables are allocated on the heap. The memory allocated in the heap area, if initialized to zero at program start, remains zero until the program makes use of it. Thus, the heap area need not contain garbage.

Pointers to objects have to be carefully managed:- Forgetting to delete a heap object or losing its pointer results in a memory leak. Using a pointer after the object it points to has been deleted, is illegal and may well crash the program!

July 5, 2011

I/O manipulation
#include <iostream.h> #include <iomanip.h> void main() { char tmp[10], tmp1[10];

cin >> setw(10) >> tmp;

cin >> setw(10) >> tmp1;

cout << tmp << " }

" << tmp1 << endl;

//abcdefghijklmnopqrstuvwxyz //abcdefghi jklmnopqr

July 5, 2011

String
#include <iostream.h> #include <string.h>

int main() { string s1("hi"); string s2("rajib");

string s3 = s1+s2;
string s4 = s3.substr(0,2); cout<<s4<<endl; }

//hi

July 5, 2011

Type cast
Typecasting is a way to make a variable of one type, such as an int, act like another type, such as a char, for one single operation. To typecast something, simply put the type of variable you want the actual variable to act as inside parentheses in front of the actual variable. #include <stdlib.h> int main() { /* The (char) is a typecast, telling the computer to interpret the 65 as a character, not as a number. It is going to give the character output of the equivalent of the number 65 (It should be the letter A for ASCII). Note that the %c below is the format code for printing a single character */ printf( "%c\n", (char)65 ); }

int main() { int a = 5000, b = 7000 ; long int c = (long int) a * b; }


Implicit: int number = 10; float value = number; value = 123.456 number = value;

//Risk: loss of precision


July 5, 2011 5

malloc
#include <stdio.h> int main() { int *ptr_one; ptr_one = (int *)malloc(sizeof(int)); if (ptr_one == 0) { printf("ERROR: Out of memory\n"); return 1; } *ptr_one = 25; printf("%d\n", *ptr_one); free(ptr_one); return 0; } C++: ptr_one = new int; ptr_one = new int [5]; //array struct node { int data; struct node *next; }; struct node *head = NULL; struct node *n1, *n2, *n3; n1 = (struct node *) malloc(sizeof(struct node)); n2 = (struct node *) malloc(sizeof(struct node)); n3 = (struct node *) malloc(sizeof(struct node)); head = n1; n1->data = 1; n1->next = n2; n2->data = 2; n2->next = n3; n3->data = 3; n3->next = NULL; /* <-- indicates end of list */

July 5, 2011

Function pointer
int f1() { cout << f1 method; } int f2() { cout << f2 method; } int f3() { cout << f3 method; } int (*ptrfunc)(); if (cond1) ptrfunc = f1; else if (cond2) ptrfunc = f2; else ptrfunc = f3;

// call function via pointer ptrfunc();


// alternate call function via pointer (*ptrfunc)();

July 5, 2011

Function pointer
#include <iostream.h>

// Function Prototypes bool MainMenu(); bool Game(); bool OptionsMenu(); bool Exit();
bool (*g_FuncPointer)();

MainMenu() { int input; cout << "Main Menu" << endl; cout << "1) Start Game 2) Options 3) Exit: "; cin >> input; switch (input) { case 1: g_FuncPointer = Game; break; case 2: g_FuncPointer = OptionsMenu; break; case 3:bool g_FuncPointer = Exit; break; } return true; // only the exit function will return false }

bool OptionsMenu() { int input; cout << "Options Menu currently no options" << endl; cout << "1) Main Menu: "; cin >> input; switch (input) { case 1: g_FuncPointer = MainMenu; break; } return true; } bool Exit() { int input; cout << "Exit game?" << endl; cout << "0) No 1) Yes "; cin >> input; switch (input) { case 0: g_FuncPointer = MainMenu; break; case 1: return false; } return true; }

bool Game() { int input; cout << "You are currently playing the game!" << endl; cout << "1) Menu 2) Exit: "; cin >> input; switch (input) { case 1: g_FuncPointer = MainMenu; break; case 2: g_FuncPointer = Exit; break; }

int main() { g_FuncPointer = MainMenu;


bool playing = true; while (playing) { playing = g_FuncPointer(); } return 0; }

return true; // only the exit function will return false }

July 5, 2011

namespace
Namespaces allow to group entities like classes, objects and functions under a name. This way the global scope can be divided in "sub-scopes", each one with its own name.

#include <iostream>
using namespace std; namespace first { int x = 5; int y = 10; }

int main ()
{ using namespace first; cout << x << endl; cout << y << endl; cout << second::x << endl; cout << second::y << endl;

int main ()
{ { using namespace first; cout << x << endl; } {

namespace second
{ double x = 3.1416; double y = 2.7183; } int main ()

return 0;
} }

using namespace second;


cout << x << endl;

return 0; }

{
using first::x; using second::y; cout << x << endl; cout << y << endl; cout << first::y << endl; cout << second::x << endl; return 0; }

July 5, 2011

Virtual bases: Multiple inheritance


#include <iostream.h> //Virtually derived class //Order of calling the constructors //The order of searching for a method class DERIVED_3:public DERIVED_1, public DERIVED_2 { private : //Private data //BASE Constructor //BASE Constructor //DERIVED_1 Constructor //BASE Constructor

class BASE
{ private : //Private data public : BASE() {cout << "BASE Constructor" << endl;} void display(void); }; class DERIVED_1:virtual public BASE { private : //Private data public : DERIVED_1() {cout << "DERIVED_1 Constructor" << endl;} void display(void);

public : DERIVED_3() {cout << "DERIVED_3 Constructor" << endl;}


}; void BASE::display(void) { cout << "BASE : display method is called" << endl; }

//DERIVED_2 Constructor
//BASE Constructor //DERIVED_1 Constructor //DERIVED_2 Constructor //DERIVED_3 Constructor //BASE : display method is called

void DERIVED_1::display(void)
{ cout << "DERIVED_1 : display method is called" << endl; } int main(void) { BASE base; DERIVED_1 derived_1;

//DERIVED_1 : display method is called


//BASE : display method is called //DERIVED_1 : display method is called

};
class DERIVED_2:public virtual BASE { private : //Private data public : DERIVED_2() {cout << "DERIVED_2 Constructor" << endl;} };

DERIVED_2 derived_2; DERIVED_3 derived_3; base.display(); derived_1.display();

derived_2.display();
derived_3.display(); return 0; }//End of main()
July 5, 2011 10

Vector
#include <vector> #include <string> #include <iostream.h> using namespace std; Vector constructors create vectors and initialize them with some data Vector operators compare, assign, and access elements of a vector assign assign elements to a vector at returns an element at a specific location back returns a reference to last element of a vector void main() { //Declaration for the string data string strData = "One"; //Declaration for C++ vector begin returns an iterator to the beginning of the vector capacity returns the number of elements that the vector can hold clear removes all elements from the vector empty true if the vector has no elements end returns an iterator just past the last element of a vector

vector <string> str_Vector;


str_Vector.push_back(strData); strData = "Two"; str_Vector.push_back(strData); strData = "Three"; str_Vector.push_back(strData);

erase removes elements from a vector


front returns a reference to the first element of a vector insert inserts elements into the vector max_size returns the maximum number of elements that the vector can hold pop_back removes the last element of a vector push_back add an element to the end of the vector

strData = "Four";
str_Vector.push_back(strData); }

rbegin returns a reverse_iterator to the end of the vector


rend returns a reverse_iterator to the beginning of the vector reserve sets the minimum capacity of the vector resize change the size of the vector size returns the number of items in the vector swap swap the contents of this vector with another

July 5, 2011

11

Pure virtual
#include <iostream.h> class BASE { private://private data protected: BASE(){} public: //Pure virtual function virtual void display(void) = 0; }; } int main(void) class DERIVED_1:public BASE { private://private data public: DERIVED_1() {} void display(void); }; { BASE *bastptr; //BASE base; //illegal, since BASE is an abstract class DERIVED_1 derived_1; DERIVED_2 derived_2; bastptr = &derived_1; bastptr->display(); class DERIVED_2:public BASE { private://private data public: DERIVED_2() {} void display(void); return 0; }//End of main() bastptr = &derived_2; bastptr->display(); } void DERIVED_2::display(void) { void DERIVED_1::display(void) { cout << "DERIVED_1 : display method is called" << endl;

cout << "DERIVED_2 : display method is called" << endl;

};

//DERIVED_1 : display method is called //DERIVED_2 : display method is called


July 5, 2011 12

Pure virtual with body


#include <iostream.h> class shape { int centre; void cir::rot(int a) { cout << "cir" << endl; cent = a; cout << "cir cent = " << cent << endl; public: virtual void rot(int) = 0; }; int main() void shape::rot(int a) { { cir a; }

cout << "shape" << endl;


centre = a; cout << "shape centre = " << centre << endl; } }

a.g(5);
a.rot(4);

class cir:public shape

{
int cent; public: void rot(int); void g(int rad) { shape::rot(rad); } };

//shape
//shape centre = 5 //cir //cir cent = 4

July 5, 2011

13

Function override
#include <iostream.h> class A class B : public A {

{
private: int a; int b; public: void f1() { cout << "Class A f1 is called" << endl; a = 10; b = 20; cout << "a = " << a << endl; cout << "b = " << b << endl; }

private:
int Ba; int Bb; public: void f1() { cout << "Class B f1 is called" << endl; Ba = 10; Bb = 20; cout << "Ba = " << Ba << endl; cout << "Bb = " << Bb << endl; } }; int main() void f1(int x,int y) { cout << "Class A f1 is called" << endl; a = x; b = y; objB.f1(); { B objB;

cout << "a = " << a << endl;


cout << "b = " << b << endl; } }; }

return(0);

//objB.f1(100,200);
July 5, 2011 14

Size of class
#include <iostream> using namespace std; int main() { cout << "int: " << sizeof(int) << endl; cout << "float: " << sizeof(float) << endl; class NoVirtual { cout << "double: " << sizeof(double) << endl;

int a;
float b; double c; public: void x() const {} int i() const { return 1; }

cout << "NoVirtual: "


<< sizeof(NoVirtual) << endl; cout << "void* : " << sizeof(void*) << endl; cout << "OneVirtual: " << sizeof(OneVirtual) << endl; cout << "TwoVirtuals: "

};
} class OneVirtual { int a; public: virtual void x() const {} int i() const { return 1; } };

<< sizeof(TwoVirtuals) << endl;

//int: 4 //float: 4

//double: 8
//NoVirtual: 16 //void* : 4

class TwoVirtuals { int a; public: virtual void x() const {}

//OneVirtual: 8 //TwoVirtuals: 8

virtual int i() const { return 1; }


};

July 5, 2011

15

Macro v/s Inline


#include <iostream.h> #define PRINT(STR) cout << STR << endl; inline void PRIN(char* str) void main() { int* var; int var1; cout << str << endl; } var1 = 10; void f(int* pi, char* ps) { PRINT(pi); PRINT(ps); } } void fa(int* pi, char* ps) { PRIN(ps); } //PRIN(pi); //Illegal-passing `int *' as argument 1 of `PRIN(char *)' var = &var1; strcpy(str, "hello"); char str[10];

f(var, str);
fa(var, str);

July 5, 2011

16

Exception handling
/*For example, the following declares a class stack, which is an integer stack of a maximum of 5 elements. The class Stack declares two public nested classes Overflow and Underflow which will be used for handling those error conditions. When the stack overflow or underflows, the appropriate exceptions are thrown: */

#include <iostream.h> const int STACKMAX = 5; class Stack { public: class Overflow { public: int overflowval; Overflow(int i) : overflowval(i) {} }; class Underflow { public: Underflow() {} }; Stack() {top = -1;} void push(int item) {if (top < (STACKMAX - 1)) thestack[++top] = item; else throw Overflow(item);} int pop() {if (top > -1) return thestack[top--]; else throw Underflow();} private: int thestack[STACKMAX]; int top; //An exception class. //An exception class. //Maximum size of the stack.

#include <iostream.h> void main() { Stack mystack; int i = 5, j = 25; //Here is the try block where //exception handlers are available try { mystack.push(i); mystack.push(j); mystack.push(1); mystack.push(1234); mystack.push(999); //Stack is now full. Force an exception: mystack.push(50); //This will throw Stack::Overflow. } //Here are the exception handlers. catch(Stack::Overflow& s) { cout << "Stack has overflowed trying to push: " << s.overflowval << endl; } catch(Stack::Underflow& s) /*The program displays the following message: Stack has overflowed trying to push: 50 */

};

{
cout << "Stack underflow has occured." << endl; } } July 5, 2011 17

Friend function
#include <iostream.h> class STUDENT; //Forward declaration class STUDENT_1 { private: unsigned int number; public: void display(STUDENT); STUDENT_1() {number = 10;} }; class STUDENT { private: unsigned int marks; public: friend void STUDENT_1::display(STUDENT); int main(void) { } void STUDENT_1::display(STUDENT student) { cout << "STUDENT_1 : number = " << number << endl; cout << "STUDENT_1 : marks = " << student.marks << endl; student.marks = 100; cout << "STUDENT_1 : marks = " << student.marks << endl;

STUDENT student;
STUDENT_1 student_1;

void message(void);
STUDENT() {marks = 50;} }; void STUDENT::message(void) { cout << endl << "STUDENT : marks = " << marks << endl; } } student_1.display(student); student.message();

return 0;

//STUDENT_1 : number = 10 //STUDENT_1 : marks = 50

//STUDENT_1 : marks = 100

//STUDENT : marks = 50
July 5, 2011 18

Template
#include <iostream.h> template<class T> class A { A<int> obj(4); void main() {

T a;
obj.sho(); public: A(T t) { a = t; A<char> obj1('A'); obj1.sho();

}
void sho() { cout << a << endl; } }; }

A<double> obj2(234.567);
obj2.sho();

A<float> obj3(12.34); obj3.sho();

//4 //A //234.567 //12.34

July 5, 2011

19

Operator overloading
#include <iostream.h> class createArray { int * array; int main() { createArray obj1(5), obj2(7); cout << "obj1 size: " << obj1.getSize() << endl;

int count;
public: createArray(int element) {

cout << "obj2 size: " << obj2.getSize() << endl;

obj2 = obj1;

array = new int[element]; for(int i=0; i<element; array[i] = 0, i++); count = element; cout << "After assign obj1 size: " << obj1.getSize() << endl; cout << "After assign obj2 size: " << obj2.getSize() << endl;

}
createArray & operator= (const createArray & other) { if (this != &other) // protect against invalid self-assignment { // 1: allocate new memory and copy the elements int * new_array = new int[other.count]; for(int i=0; i<other.count; new_array[i] = other.array[i], i++); // 2: deallocate old memory delete [] array; // 3: assign the new memory to the object array = new_array; count = other.count; } return *this; // by convention, always return *this

// obj1 size: 5 // obj2 size: 7 // After assign obj1 size: 5 // After assign obj2 size: 5

}
inline int getSize(){return count;} };
July 5, 2011 20

Design pattern: Singleton


#include <iostream.h> class BASE { BASE *BASE::Instance() { if(objectPtr) BASE *BASE::objectPtr = NULL; int main(void) { BASE *obj1 = BASE::Instance(); cout << "Object exists" << endl; return (objectPtr); } cout<< "New instance" << endl; else { objectPtr = new BASE(); return(objectPtr); } } } cout << "Address: " << obj1 << endl; BASE *obj2 = BASE::Instance(); cout << "Address: " << obj2 << endl; return(0);

private:
static BASE *objectPtr; BASE() {

}
public: static BASE * Instance(); };

//New instance //Address: 0x8426008 //Object exists //Address: 0x8426008


July 5, 2011 21

Mutable
class A { public: A() : x(4), y(5) { }; mutable int x; int y; }; int main() { const A var2; var2.x = 345; // var2.y = 2345; } X() { m_accessCount = 50; value = 20; } private: } #include <iostream.h> class X { public: int test() const { m_accessCount++; // value = 10; cout << "count: " << m_accessCount << endl; cout << "value: " << value << endl; // count: 51 // value: 20 } int main() { X obj; obj.test();

mutable int m_accessCount;


int value; };
July 5, 2011 22

Design pattern: Factory


#include <iostream> #include <string> #include <vector> class Circle : public Shape { Circle() {} // Private constructor friend class Shape; Shape* Shape::factory(string type) { if(type == "Circle") return new Circle(); if(type == "Square") return new Square(); else return NULL; }

using namespace std;


class Shape { public: virtual void draw() = 0; virtual void erase() = 0;

public:
void draw() { cout << "Circle::draw\n"; } void erase() { cout << "Circle::erase\n"; } ~Circle() { cout << "Circle::~Circle\n"; } };

char* shlist[] = { "Circle", "Square", "Square",


"Circle", "Circle", "Circle", "Square", "" };

virtual ~Shape() {}
static Shape* factory(string type); }; class Square : public Shape { Square() {} // Private constructor friend class Shape; public:

int main() { vector<Shape*> shapes; for(char** cp = shlist; **cp; cp++) { shapes.push_back(Shape::factory(*cp)); } for(int i = 0; i < shapes.size(); i++) { if(shapes[i]) { shapes[i]->draw(); shapes[i]->erase(); } } return 1; }
July 5, 2011 23

void draw() { cout << "Square::draw\n"; }


void erase() { cout << "Square::erase\n"; } ~Square() { cout << "Square::~Square\n"; } };

Thank You

July 5, 2011