Beruflich Dokumente
Kultur Dokumente
Note to students: 1. Lab classes from Monday(09-08-2010) 2. Create Lab users account (non-CSE student) 3. Check course site for PRACTICE PROGRAMS
http://jatinga.iitg.ernet.in/~saradhi/cs201.html
CS201, IITG
Before OOP
Data Type + Data Structure + Abstract Data Type + Object Oriented Programming
If we consider the above points as the data to be processed by a program, how do we arrange them in memory?
Before OOP
Data Type + Data Structure + Abstract Data Type + Object Oriented Programming
Organize the points in a particular fashion and define its accessing mechanism Data Structure EX: 1. Array, RAM/DAM 2. List, Sequential
An abstract data type (ADT) is characterized by the following properties: 1. It exports a type. 2. It exports a set of operations. This set is called interface. 3. Operations of the interface are the one and only access mechanism to the type's data structure. (Encapsulation) 4. Axioms and preconditions define the application domain of the type.
Object-Oriented Concepts
In object-orientation, ADTs are referred to as classes An instance of a class is called an object Four Principles
Encapsulation Abstraction Inheritance Polymorphism
CS201, IITG
Simula 67 - first Object Oriented Language (OOL) - officially introduced by Ole Johan Dahl and Kristen Nygaard at the IFIP TC 2 Working Conference on Simulation Languages in Lysebu near Oslo in May 1967.
CS201, IITG
What is C++?
C++ is a general-purpose programming language with a bias towards systems programming that
is a better C supports data abstraction supports object-oriented programming supports generic programming
CS201, IITG
Is C a subset of C++?
In the strict mathematical sense, C isn't a subset of C++. There are programs that are valid C but not valid C++ However, C++ supports every programming technique supported by C Every C program can be written in essentially the same way in C++ with the same run-time and space efficiency. Thus, C++ is as much a superset of ANSI C
CS201, IITG
HelloWorld!
CS201, IITG
HelloWorld!
CS201, IITG
int my*Variable; char my_Str1: Int 2myID; Char _N; char __M; int break; char bool; int case;
CS201, IITG
int my*Variable; char my_Str1: Int 2myID; Char _N; char __M; int break; char bool; int case;
CS201, IITG
int my*Variable; -- Neither spaces nor punctuation marks or symbols can be part of an identifier. char my_Str1: -- Only letters (a,..z,A,...Z), digits (0,1,...9)) and single underscore characters are valid. Int 2myID; -- In addition, variable identifiers always have to begin with a letter. Char _N; char __M; They can also begin with an underline character (_ ) int break; char bool; int case;
CS201, IITG
Identifier: a sequence of one or int my*Variable; -- more letters,nor punctuation marks or symbols can Neither spaces digits or underscore be part of an identifier. characters (_).
char my_Str1: -- Only letters, digits and single underscore characters are valid. Int 2myID; -- In addition, variable identifiers always have to begin with a letter. Char _N; char __M; They can also begin with an underline character (_ )
asm, auto, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while
CS201, IITG
CS201, IITG
Scope of variables
#include <iostream> using namespace std; main() { int i; i=7; {
int j; j=i*4;
CS201, IITG
Scope of variables
#include <iostream> using namespace std; main() { int i; i=7; {
int j; j=i*4;
CS201, IITG
Initialization of variables
Initialization in C
int a = 0;
CS201, IITG
Initialization of variables
Initialization in C
int a = 0;
CS201, IITG
Introduction to strings
string myName = rahul String sName = kumar Cout << myName + sName
rahulkumar
Size() Begin() end()
CS201, IITG
Operators
Assignment (=) Relational and equality operators ( ==, !=, >, <, >=, <= ) A = 2+4 A += 2 ---- Arithmetic operators ( +, -, *, /, % ) -----Compound assignment
A+=2, a*=3
Shift operations (left shift (<<), right shift (>>))
CS201, IITG
Operators
Comma Operator execute from left to right and assign the last
CS201, IITG
Operators
CS201, IITG
Basic Input/Output
Concept: I/O operations act on streams (sequences) of ASCII characters Valid to use the same I/O statements in C++ as in C: printf, scanf, and others in stdio.h C++ provides an alternative with the new stream input/output features: cin and cout cin: Used for keyboard input (std::cin) cout: Used for screen output (std::cout) Both cin and cout are data objects and are defined by a classes
CS201, IITG
Basic Input/Output
Concept: I/O operations act on streams (sequences) of ASCII characters Valid to use the same I/O statements in C++ as in C: printf, scanf, and others in stdio.h C++ provides an alternative with the new stream input/output features: cin and cout C++ uses message passing mechanism cin: Used forto communicateinput (std::cin) keyboard between objects cout: Used for screen output (std::cout) Both cin and cout are data objects and are defined by a classes
CS201, IITG
CS201, IITG
CS201, IITG
iostream contains basic information required for all stream I/O operations fstream used for performing file I/O operations
CS201, IITG
A stream
A flow of character Intermadiate Storage (Buffers): IO to streams goes through a buffer. C++ allows the programmer to change the default behaviour of the associated buffer State: each stream is associated with a state indicating various things like if an error has occur or not
CS201, IITG
IO Class Heirarchy
CS201, IITG
IO Stream
Example:
Control Structures
if and else
if (condition) statement
CS201, IITG
CS201, IITG
CS201, IITG
CS201, IITG
Control Structures
Jump statements
CS201, IITG
Control Structures
Jump statements
CS201, IITG
Control Structures
Jump statements
CS201, IITG
Control Structures
Jump statements
Terminate the program Exitcode 0: normal termination Others, termination due to error or unexpected results
CS201, IITG
Control Structures
Jump statements
Switch
CS201, IITG
C++ Class
CS201, IITG
Class Structure
class className{ access_specifier_1: members; access_specifier_2: members; access_specifier_3: members; . } objectName;
An access specifier is one of the following three private: accessible within other members of the same class and their friends. protected: accessible within other members of the same class, their friends and derived classes public: accessible from anywhere the class is visible Default access specifier is private
Example
class aRectangle{ private: int x; int y; public: void setValue(int,int); int area(); } myRect;
An access specifier is one of the following three private: accessible within other members of the same class and their friends. protected: accessible within other members of the same class, their friends and derived classes public: accessible from anywhere the class is visible Default access specifier is private
Example
class aRectangle{ int x; int y; public: void setValue(int,int); int area(); }; void aRectangle::setValue(int a, int b) { x=a; y=b; } int aRectangle::area() { return x*y; } class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; } };
class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; } }; int main() { aRectangle a; a.setValue(2,4); cout << area :<<a.area(); return 0; }
Example
int main() { aRectangle a, b; a.setValue(2,4); cout << area of a:<<a.area(); b.setValue(3,4); cout << area of b:<<b.area(); return 0; }
a 2 4 b 3 4
setValue(int,int) area()
setValue(int,int) area()
Class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; Can we do } }; int main() { aRectangle a; a.setValue(2,4); cout << area :<<a.area(); return 0; }
Example
int main() { aRectangle a, b; a.setValue(2,4); cout << area of a:<<a.area(); b.setValue(3,4); cout << area of b:<<b.area(); return 0; } a.x=10
b 2 4 3 4
data encapsulation
setValue(int,int) area()
setValue(int,int) area()
class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; } }; int main() { aRectangle a; a.setValue(2,4); cout << area :<<a.area(); return 0; }
Example
What if a.setValue(2,4); is before cout << area :<<a.area();
class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; } }; int main() { aRectangle a; a.setValue(2,4); cout << area :<<a.area(); return 0; }
Example
What if a.setValue(2,4); is before cout << area :<<a.area();
class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; } }; int main() { aRectangle a; a.setValue(2,4); cout << area :<<a.area(); return 0; }
Constructor
Constructor
A function that initializes the members of an object Same name as that of class It has No return type. No return statement. It is used at the time of object creation. Constructors are never virtual
Constructor
A function that initializes the members of an class Foo object { Same name }; that of class as void function(Foo &arg) It has { } No return type.main() int { No return statement. Foo& f = Foo(); // error. It is used at the time of object creation. function(Foo()); // error const Foo& f2 = Foo(); // OK Constructors}are never virtual
Constructor Types
Default Constructor
Constructor with no parameters
Class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } Default Constructor aRectangle(int a,int b) If no constructor is defined in a class { x=a; default values (if It just allocates the memory space and assigns they=b; } any) int area() Overloading Constructors { return x*y; Many constructors with different parameters } };
Constructor Type
int main() { aRectangle a(2,4); cout << area : << a.area(); return 0; }
Constructor Type
Default Constructor
Constructor with no parameters
Default constructor is called It just allocates the memory space and assigns the default values (if any)
Overloading Constructors Many constructors with different parameters Other Types of constructors Copy constructors: Initialize an object by another object Conversion constructors: Convert from the type of the argument to the class type.
Destructors
use to deallocate memory and cleanup the resources for an object and its members when the object is destroyed. call when the object passes out of scope or is explicitly deleted. takes no arguments and has no return type Its address cannot be taken. Destructors cannot be declared const, volatile, const volatile or static. A destructor can be declared virtual or pure virtual.
Destructors
Const
-- const int Constant1 memory and cleanup the resources for use to deallocate -- const int * Constant2 object and its members when the object is destroyed.
an
passes out of scope or is explicitly deleted. takes no arguments and has no return type -- int * const Constant3 Its address cannot be taken. -- int const * const cannot be declared const, volatile, const volatile or Destructors Constant4 static. A destructor can be declared virtual or pure virtual.
object and its members when the object is destroyed. call -- int * const object passes out of scope or is explicitly deleted. when the Constant3 declares that Constant3 is constant pointer to a variable integer an takesint const * const Constant4 no return type no arguments and has -Its address cannot be taken. Destructors cannot be declared const, volatile, const volatile or static. A destructor can be declared virtual or pure virtual.
Class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } use to deallocate memory and cleanup aRectangle(int a,int b)an the resources for object and its members when the object is destroyed. { x=a; y=b; } call when the object passes out of scope or is explicitly deleted. ~aRectangle(){ } takes no arguments and has no return type int area() { return x*y; Its address cannot be taken. } Destructors cannot be declared const, volatile, const volatile or };
Destructors
aRectangle a(2,4);
What is a pointer?
int x = 10; int *p; p = &x;
p 10 x
What is a pointer?
int x = 10; int *p; p = &x; *p = 20; *p is the value at the address p.
p 20 x
What is a pointer?
int x = 10; int *p = NULL; p = &x; *p = 20; Declares a pointer to an integer
new allocates space to hold the object. new calls the objects constructor. new returns a pointer to that object.
// ok // ok
Initializes an array of 10 integers on the heap. C++ equivalent of the following C code
int* nums = (int*)malloc(x * sizeof(int));
Initializes a multidimensional array Only the first dimension can be a variable. The rest must be constants. Use single dimension arrays to fake multidimensional ones
Few questions?
class A { int x; public: void display(){ cout << x <<endl; } }; main() { A a; a.display(); A b=A(); b.display(); } class A { const int x; public: void display(){ cout << x <<endl; } }; main() { A a; a.display(); } class A { static int x; public: void display(){ cout << x <<endl; } }; main() { A a; a.display(); }
class A { static const int x=12; public: void display(){ cout << x <<endl; } }; main() { A a; a.display(); }
Few questions?
class A { int x; public: A(int a){ x=a; } void display(){ cout << x <<endl; } }; main() { A a; a.display(); } class A { int x; public: A(int a=20){ x=a; } void display(){ cout << x <<endl; } }; main() { A a; a.display(); } class A { int x; public: A(int a=20){ x=a; } void display(){ cout << x <<endl; } }; main() { A a; a.display(); } typedef class A { int x; public: void B(){ x=10;} A(){ x=20; } void display(){ cout << x <<endl; } }B; main() { B a; a.display(); }
Class Allocation
Like Static and Dynamic allocation in C, C+ + also support static and dynamic allocation Class allocations
Static allocation
aRectangle a(3,5);
Copy Constructor
Create an object as a copy of another object Required when Pass an object as a parameter to a function Pass by value Return an object from a function Return by value Assign a class to another If no copy constructor is defined, create a default copy constructor Copy the data members of the source object to the data member of the target object
Copy Constructor
Syntax
takes a reference to a const parameter. its first parameter a (possibly const or volatile) reference to its own class type. If more than one argument, the rest must have default values associated with them. <class name>(const <class name>& object, ); aRactangle ( const aRactangle & b, );
Copy Constructor
Syntax
Examples
X(const X& copyFromMe); takes a reference to a const parameter. X(const volatile X& copyFromMe); its first parameter a (possibly const or volatile) reference to its own class type. X(volatile X& copyFromMe); If more than one argument, the rest must have default X(const X& copyFromMe, values associated with them. int = 10); X(const X& copyFromMe, double = 1.0, int <class name>(const <class name>& object, ); = 40); aRactangle ( const aRactangle & b, );
Copy Constructor
Create an object as a copy of another object Required when Example: Pass an object as a parameter to a function 1. aRectangle a(2,4); // not a copy constructor 2. aRectangle b(a); // a copy constructor used a the time building an Pass by value object Return an object from a function 3. aRectangle c=a; //copy constructor is used to initialize in Return by value declaration. 4. aRectangle d; Assign a class to another d=a; // Assignment operator, no constructor or copy constructor. If no copy constructor is defined, create a default copy 5. myFunction(p); // copy constructor involved constructor 6. d=myObjectReturnFunction(); // copy constructor involved Copy the data members of the source object to the data member of the target object
class aRectangle{ Class aRectangle{ int * x; int * x; int * y; int * y; public: public: aRectangle() aRectangle() { x= new int(6); y= new int(2); } { x= new int(6); y= new int(2); } aRectangle(int a,int b) aRectangle(int a,int b) { x= new int(a); y=new int(b); { x= new int(a); y=new int(b); } } int reset(int a, int b) int area() { *x=a; *y=b; } { return (*x)*(*y); int area() { return (*x)*(*y); } } }; }; int main() int main() { aRectangle a(2,4); { aRectangle a(2,4); aRectangle b =a; aRectangle b =a; cout << a.area()<< << b.area(); } a.reset(2,10); cout << a.area()<< << b.area(); }
class aRectangle{ int * x; int * y; public: aRectangle() { x= new int(6); y= new int(2); } aRectangle(int a,int b) { x= new int(a); y=new int(b); } int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } }; int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area(); a.reset(2,10); cout << a.area()<< << b.area(); }
class aRectangle{ int * x; int * y; public: aRectangle() { x= new int(6); y= new int(2); } aRectangle(int a,int b) { x= new int(a); y=new int(b); } int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } }; int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area();
88 20 8
}
class aRectangle{ int * x; int * y; public: aRectangle() Output? { x= new int(6); y= new int(2); } When aRectangle a(2,4) executed aRectangle(int a,int b) 88 { x= new int(a); y=new int(b); 2 x } 88 int reset(int a, int b) { *x=a; *y=b; } 4 y int area() { return (*x)*(*y); } }; a8 8 int main()
20 20
88 20 8
}
When aRectangle b=a executed class aRectangle{ int * x; int * y; 2 x public: aRectangle() Output? 4 { x= new int(6); y= new int(2); } y aRectangle(int a,int b) a 88 { x= new int(a); y=new int(b); } 88 int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } x }; 88
20 20
int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area();
88 20 8
}
class aRectangle{ int * x; int * y; public: aRectangle() { x= new int(6); y= new int(2); } aRectangle(int a,int b) { x= new int(a); y=new int(b); } int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } }; int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area();
88 20 8
}
When aRectangle b=a executed class aRectangle{ int * x; int * y; x 2 public: aRectangle() Output? { x= new int(6); y= new int(2); } 4 y aRectangle(int a,int b) a 88 { x= new int(a); y=new int(b); } 88 int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } x 2 }; 88 b y 20 20 4 int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area();
88 20 8
}
class aRectangle{ int * x; int * y; public: aRectangle() { x= new int(6); y= new int(2); } aRectangle(int a,int b) { x= new int(a); y=new int(b); } aRectangle(const aRectangle & a) { x= new int(a.x); y= new int(a.y); } int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } }; int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area();
88 20 8
}
class aRectangle{ int * x; int * y; public: aRectangle() { x= new int(6); y= new int(2); } aRectangle(int a,int b) { x= new int(a); y=new int(b); } aRectangle(const aRectangle & a) { if(this != &a) { this->x= new int(a.x); this->y= new int(a.y); } } int reset(int a, int b) { *x=a; *y=b; } int area() { return (*x)*(*y); } }; int main() { aRectangle a(2,4); aRectangle b =a; cout << a.area()<< << b.area(); a.reset(2,10); cout << a.area()<< << b.area(); }
Conversion Constructor
Example
int a(2); string(hello); double a = 2 + 3.5; string b =hello; Above Examples are implicit conversion It involves a temporary object double a= 2 +3.5
It is equivalent to
double temp =(double) 2 double a =temp + 3.5
Conversion Constructor
A constructor with single parameter of other type The compiler uses this idiom as one way to infer conversion rules for a class. Compiler updates its type conversion rules.
Example
class Task { private: int pid; string name; public: Task(int num, const string & n) { pid=num; name=n; } void display(){cout << name<,endl;} }; main() { Task a(5,hello); a.display(); }
Example
class Task { private: int pid; string name; public: Task(int num): name(hello) { pid=num; } void display(){cout << name<,endl;} }; main() { Task a(5); a.display(); }
Class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } int area() { return x*y; } }; int main() { aRectangle a(2,4); cout << area<< a.x*a.y; return 0;
Friend Function
Syntax:
friend <return_type> [<class_name> ::] function ( args );
Friend function is not a member function of the class A friend function has full access to private and public member of a class. A function can be a friend with any number of classes
It is possible to declare the friend function as either private or public.
Friend Function
public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } }; void width() { aRectangle b; cout << b.x <<endl;} int main() { aRectangle a(2,4); width(); return 0; }
Friend class
Syntax
A class x can be declared as a friend of some other class y The friend class x is not a member of y The member functions of y have full access to private and public members of x. A class can be a friend with any number of classes
It is possible to declare the friend class as either private or public.
Friend class
class aRectangle{ int x; int y; friend class myFriend; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } }; class myFriend{ aRectangle a; public: void myFrdX(){ cout << a.x <<endl; }; int main() { myFriend b; b.myFrdX(); return 0; }
Friend class
class aRectangle{ int x; int y; friend class myFriend; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } output? }; class myFriend{ aRectangle a; public: void myFrdX(){ cout << a.x <<endl; }; int main() { myFriend b; b.myFrdX(); return 0; }
Friend
Bjarne Stoustrup (the creator of C++)
Use friend with good judgment. The private access modifier was created for a good reason: encapsulation and data security. In other words, don't use "friend" as a hacker.
Overloading
Overloading (Polymorphism)
more than one definition for a function name or an operator in the same scope
Function overloading
Overload a function with multiple functionality
Operator overloading
Allow an operator to apply on different format
Function Overloading
Identify the function by the signature The parameters represent the signature void AddAndDisplay(int x, int y) { cout<<" C++ Tutorial - Integer result: "<<(x+y); } void AddAndDisplay(double x, double y) { cout<< " C++ Tutorial - Double result: "<<(x+y); } void AddAndDisplay(float x, float y) { cout<< " C++ Tutorial - float result: "<<(x+y); } int AddAndDisplay(int x, int y) { cout<<" C++ Tutorial - Integer result: "<<(x+y); return x+y }
Function Overloading
Identify the function by the signature The parameters represent the signature void AddAndDisplay(int x, int y) { cout<<" C++ Tutorial - Integer result: "<<(x+y); } void AddAndDisplay(double x, double y) { cout<< " C++ Tutorial - Double result: "<<(x+y); } void AddAndDisplay(float x, float y) { cout<< " C++ Tutorial - float result: "<<(x+y); } int AddAndDisplay(int x, int y) { cout<<" C++ Tutorial - Integer result: "<<(x+y); return x+y }
Operator Overloading
Allows built-in operators for user defined type
+ * / % ^ & | ~
<
>
+=
-=
*=
/=
%=
^=
&=
|=
<<
>>
<<=
>>=
==
!=
<=
>=
&&
||
++
--
->*
->
()
[]
new
delete
new[]
delete[]
Operator Overloading
You can not overload these operators
. #
.*
::
?:
Operator Overloading
Syntax:
<return type> operator <symbol> (args) {..}
Example
aRectangle a;
++a; ++(++a); a=b; a=(c=(b+=d));
Example: unary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } void operator ++(){ ++ x; ++y; } }; int main() { myFriend b; ++b; ++(++b); return 0; }
Example: unary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } void operator ++(){ ++ x; ++y; } }; int main() { myFriend b; ++b; ++(++b); return 0; }
Comment?
Example: unary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } aRectangle operator ++(){ ++ x; ++y; return *this} }; int main() { myFriend b; ++(++b); cout << b.area(); return 0; }
Output? 21 or 32
Example: unary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } }; void operator ++(aRectangle b) { ++ b.x; ++b.y; } int main() { myFriend b; ++b; return 0; }
Comment?
Example: unary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } }; void operator ++(aRectangle b) { ++ b.x; ++b.y; } int main() { myFriend b; ++b; return 0; }
Example: unary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } }; void operator ++(aRectangle b) { ++ b.x; ++b.y; } int main() { myFriend b; ++b; return 0; }
Example: binary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } void operator +(aRectangle b) { x=x+b.x; y=y+b.y; } }; int main() { myFriend b,a; a=a+b; return 0; }
Example: binary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } void operator +(aRectangle b){ x=x+b.x; y=y+b.y; } }; int main() { myFriend b,a; a=a+b; return 0; }
Comments?
Example: binary
class aRectangle{ int x; int y; public: aRectangle() { x=6; y=2; } aRectangle(int a,int b) { x=a; y=b; } ~aRectangle(){ } int area() { return x*y; } aRectangle operator +(aRectangle b) { x=x+b.x; y=y+b.y; return *this; } }; int main() { myFriend b,a; a=a+b; return 0; }
Return
Self Study:
Overloading for other operators
Class Inheritance
Vehicle
Bus
Class Inheritance
class A { private: int A_x; protected: int A_y; public: void A_f1() };
Base Class
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
Derive Class
Class Inheritance
class A { private: int A_x; protected: int A_y; public: void A_f1() };
Inheritance is referred to as
B is "a kind of a" A B is "derived from" A B is "a specialized" A B is a "subclass" of A B is a "derived class" of A A is the "base class" of B A is the "superclass" of B
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
Derive classes inherites the protected and public members of base class
Class Inheritance
class A { private: int A_x; protected: int A_y; public: void A_f1() };
Inheritance can be of
public: protected members are inherited as protected and public members are inherited as public members private: inherited as private members protected: inherited as protected members
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
Class Inheritance
class A { private: int A_x; protected: int A_y; public: A(..){..} void A_f1() };
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
When we create an object of derived class the base class constructor is called and then the derived class constructor is called. base class constructor initializes its data members and the derived class constructor initializes the derived classes data members. by default, default constructor is called Otherwise, need to call initializer
Class Inheritance
class A { private: int A_x; protected: int A_y; public: A(int){......} void A_f1() };
Error
class B : public A { private: int B_x; protected: int B_y; public: B{....} void B_f1(); };
Class Inheritance
class A { private: int A_x; protected: int A_y; public: A(int){......} void A_f1() };
class B : public A { private: int B_x; protected: int B_y; public: B:A(10){....} void B_f1(); };
Class Inheritance
class A { private: int A_x; protected: int A_y; public: void A_f1() };
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
Class Inheritance
class A { private: int A_x; protected: int A_y; public: void A_f1() };
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
A Class In Memory
class A { private: int A_x; protected: int A_y; public: }; void A_f1()
A a;
int A_x int A_y a contiguous region of memory. A pointer to the first byte of that region of memory.
class B : public A { private: int B_x; protected: int B_y; public: }; void B_f1();
From Memory
class A { private: int A_x; protected: int A_y; public: }; void A_f1()
A a;
int A_x int A_y a contiguous region of memory. A pointer to the first byte of that region of memory.
class B : public A { private: int B_x; protected: int B_y; public: }; void B_f1();
From Memory
class A { private: int A_x; protected: int A_y; public: }; void A_f1()
A a;
int A_x int A_y a contiguous region of memory. A pointer to the first byte of that region of memory.
class B : public A { private: int B_x; protected: int B_y; public: }; void B_f1();
From Memory
class A { private: int A_x; protected: int A_y; public: }; void A_f1(int)
A a;
int A_x int A_y a contiguous region of memory. A pointer to the first byte of that region of memory.
class B : public A { private: int B_x; protected: int B_y; public: }; void B_f1();
The call to function A_f1() is converted to an ordinary function call by the compiler. Ex: A *pt; pt->A_f1(10); is converted to f__F1A(pt,10);
From Memory
class A { private: int A_x; protected: int A_y; public: }; void A_f1()
A a;
int A_x int A_y a contiguous region of memory. A pointer to the first byte of that region of memory.
class B : public A { private: int B_x; protected: int B_y; public: }; void B_f1();
B b;
int A_y int B_x int B_x
From Memory
class A { private: int A_x; protected: int A_y; public: }; void A_f1()
A a;
int A_x int A_y a contiguous region of memory. A pointer to the first byte of that region of memory.
class B : public A { private: int B_x; protected: int B_y; public: }; void B_f1();
B b;
int A_x int A_y int B_x int B_x
Multiple Inheritance
class A { private: int A_x; protected: int A_y; public: void A_f1() }; class C { private: int C_x; protected: int C_y; public: void C_f1() };
class B : public A, public C { private: int B_x; protected: int B_y; public: void B_f1(); };
class C : public B{ private: int C_x; protected: int C_y; public: void C_f1() };
class B : public A { private: int B_x; protected: int B_y; public: void B_f1(); };
class List { int array[100]; int count; public: List(): count(0) {} void Insert(int n) { array[count++]=n; } int Get(int i) { return array[i]; } int Size() { return count; } }; void ManipList(List list) { list.Insert(100); list.Insert(200); } class TotalingList: public List { int total; public: TotalingList(): List(), total(0) {} void Insert(int n) { total += n; List::Insert(n); } int GetTotal() { return total; } }; int main() { TotalingList list; int x; list.Insert(10); list.Insert(5); cout << list.GetTotal() << endl; ManipList(list); cout << list.GetTotal() << endl; for (x=0; x < list.Size(); x++) cout << list.Get(x) << ' '; cout << endl; return 0;}
class List { int array[100]; int count; public: List(): count(0) {} void Insert(int n) { array[count++]=n; } int Get(int i) { return array[i]; } int Size() { return count; } }; void ManipList(List list) { list.Insert(100); list.Insert(200); } class TotalingList: public List { int total; public: TotalingList(): List(), total(0) {} void Insert(int n) { total += n; List::Insert(n); } int GetTotal() { return total; } }; int main() { TotalingList list; int x; list.Insert(10); list.Insert(5); cout << list.GetTotal() << endl; ManipList(list); 15 cout << list.GetTotal() << endl; 15 for (x=0; x < list.Size(); x++) 10 5 cout << list.Get(x) << ' '; cout << endl; return 0;}
class List { int array[100]; int count; public: List(): count(0) {} void Insert(int n) { array[count++]=n; } int Get(int i) { return array[i]; } int Size() { return count; } }; void ManipList(List& list) { list.Insert(100); list.Insert(200); } class TotalingList: public List { int total; public: TotalingList(): List(), total(0) {} void Insert(int n) { total += n; List::Insert(n); } int GetTotal() { return total; } }; int main() { TotalingList list; int x; list.Insert(10); list.Insert(5); cout << list.GetTotal() << endl; ManipList(list); cout << list.GetTotal() << endl; for (x=0; x < list.Size(); x++) cout << list.Get(x) << ' '; cout << endl; return 0;}
class List { int array[100]; int count; public: List(): count(0) {} void Insert(int n) { array[count++]=n; } int Get(int i) { return array[i]; } int Size() { return count; } }; void ManipList(List& list) { list.Insert(100); list.Insert(200); } class TotalingList: public List { int total; public: TotalingList(): List(), total(0) {} void Insert(int n) { total += n; List::Insert(n); } int GetTotal() { return total; } }; int main() { TotalingList list; int x; list.Insert(10); list.Insert(5); cout << list.GetTotal() << endl; ManipList(list); 15 cout << list.GetTotal() << endl; 15 for (x=0; x < list.Size(); x++) 10 5 100 200 cout << list.Get(x) << ' '; cout << endl; return 0;}
class List { int array[100]; int count; public: List(): count(0) {} virtual void Insert(int n) { array[count++]=n; } int Get(int i) { return array[i]; } int Size() { return count; } }; void ManipList(List& list) { list.Insert(100); list.Insert(200); } class TotalingList: public List { int total; public: TotalingList(): List(), total(0) {} void Insert(int n) { total += n; List::Insert(n); } int GetTotal() { return total; } }; int main() { TotalingList list; int x; list.Insert(10); list.Insert(5); cout << list.GetTotal() << endl; ManipList(list); 15 cout << list.GetTotal() << endl; 315 for (x=0; x < list.Size(); x++) 10 5 100 200 cout << list.Get(x) << ' '; cout << endl; return 0;}
Virtual Function
Virtual function is a member function of a class that is declared using the keyword "virtual". A pointer to a derived class object may be assigned to a base class pointer and a virtual function called through the pointer.
f()
f()
f()
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual void A_f1() };
int main(){ B *tpB = new B(); C *tpC = new C(); A *ptA = tpB; ptA->A_f1(); ptA = tpC; ptA->A_f1(); Output: B C
class B : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} };
class C : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << C;} };
In the memory
Compiler creates a virtual table for each class containing virtual function. The v-table consists of addresses to the virtual functions for classes and pointers to the functions from each of the objects of the derived class. Whenever there is a function call made to the virtual function, the v-table is used to resolve to the function address. Dynamic binding happens during a virtual function call
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual void A_f1() };
B *tpB = new B(); C *tpC = new C(); A *ptA = tpB; ptA->A_f1(); ptA = tpC; ptA->A_f1(); Output: B C
Self Study
class B : public A { What is advantage and disadvantages class B : public A { private: of virtual machine? private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} int B_x; protected: int B_y; public: void A_f1(){cout << C;}
};
};
Virtual Function
Every derived class should have a definition virtual void function_name() = 0; act as expressions of general concepts from which more specific classes can be derived. one cannot create an object of an abstract class type can use pointers and references to abstract class types. A class that contains at least one pure virtual function is considered an abstract class
Abstract class
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual int A_f0() {return 0;} virtual void A_f1()=0 { cout << A;} };
A a; a.A_f0()
class B : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} };
class C : public A { private: int B_x; protected: int B_y; public: void C_f1(){cout << C;} };
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual int A_f0() {return 0;} virtual void A_f1()=0 { cout << A;} };
A a; a.A_f0()
Error?
class B : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} };
class C : public A { private: int B_x; protected: int B_y; public: void C_f1(){cout << C;} };
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual int A_f0() {return 0;} virtual void A_f1()=0 { cout << A;} };
A a; a.A_f0()
class B : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} };
class C : public A { private: int B_x; protected: int B_y; public: void C_f1(){cout << C;} };
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual int A_f0() {return 0;} virtual void A_f1()=0 { cout << A;} };
A a; a.A_f0()
No definition of A_f1()
class B : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} };
class C : public A { private: int B_x; protected: int B_y; public: void C_f1(){cout << C;} };
Virtual Function
class A { private: int A_x; protected: int A_y; public: virtual int A_f0() {return 0;} virtual void A_f1()=0 { cout << A;} };
A a; a.A_f0()
class B : public A { private: int B_x; protected: int B_y; public: void A_f1(){cout << B;} };
class C : public A { private: int B_x; protected: int B_y; public: void C_f1(){cout << C;} };
class Account { public: Account( double d ) { _balance = d; } virtual double GetBalance() { return _balance; } virtual void PrintBalance() { cout<<"bal: "<<GetBalance() << endl; } private: double _balance; }; class CheckingAccount : public Account { public: CheckingAccount(double d) : Account(d) {} void PrintBalance() { cout<<"bal: "<<GetBalance() << endl; } }; class SavingsAccount : public Account { public: SavingsAccount(double d) : Account(d) {} void PrintBalance() { cout<<"bal: "<<GetBalance() << endl; } }; int main() { CheckingAccount *pChecking = new CheckingAccount( 200.00 ) ; SavingsAccount *pSavings = new SavingsAccount( 240.00 ); Account *pAccount = pChecking; pAccount->PrintBalance(); pAccount = pSavings; pAccount->PrintBalance();
Templates
Before Template, see the following example We have a function to add two double numbers
double add(double a, double b){ return a+b; } We also need functions for two int numbers, then we need another function int add(int a, int b){ return a+b; }
Or, say we have an array of int, and we also want to use it for storing array of char
Templates
Before Template, see the following example We have a function to add two double numbers
double add(double a, double b){ return a+b; } We also need functions for two int numbers, then we need another function int add(int a, int b){ return a+b; }
Or, say we have an array of int, and we also want to use it for storing array of char
Soln: Templates
Templates
A mechanism to generalize the datatype Help us to write code without being tied to particular type. Template can be of two types
Class Template
class aRectangle{ int x; int y; public: void setValue(int a,int b) { x=a; y=b; } int area() { return x*y; } };
template <class T> class aRectangle{ T x; T y; public: void setValue(T a,T b); T area(); }; template <class T> void aRectangle <T>::setValue(T a,T b) { x=a; y=b; } template <class T> T aRectangle <T>::area() { return x*y; } }
int main() { aRectangle <int> a; a.setValue(2,4); cout << area :<<a.area(); return 0; } int main() { typedef aRectangle<int> IntRec; IntRec a; a.setValue(2,4); cout << area :<<a.area(); return 0;
template <class T> class aRectangle{ T x; T y; public: void setValue(T a,T b); T area(); }; template <class T> void
int main() { aRectangle <int> a; a.setValue(2,4); cout << area :<<a.area(); return 0;
aRectangle <T>::setValue(T a,T b) { x=a; y=b; } template <class T> T aRectangle <T>::area() { return x*y; }
Template Parameters
Three types
datatype integral or enumeration pointer to object or pointer to function reference to object or reference to function pointer to member A template as the parameter of another template
Typename
In the above examples, we used <class T> It is a generalized format. If the template parameter is a type parameter, then <class T> is same as <typename T> <typename T> indicates that template parameter is type Usage:
Use the keyword typename if you have a qualified name that refers to a type and depends on a template parameter. Ex: standard datatypes.
Name Binding
The process of finding the declaration for each name that is explicitly or implicitly used in a template. The compiler may bind a name in the definition of a template, or it may bind a name at the instantiation of a template.
template <class T> class aRectangle{ T x; T y; int z; public: void setValue(T a,T b) { x=a; y=b; } T area() { return x*y; } };
Dependent Name
A dependent name is a name that depends on the type or the value of a template parameter. For example:
template<class T> class U : A<T> { T::B x; void f(A<T>& y) { *y++; } };
Dependent names are: the base class A<T> the typename T::B the variable y.
Dependent Name
A dependent name is a name that depends on the type or the value of a template parameter. For example:
A qualified dependent name such as T::x can be: * A nontype (object or function) * A type * A template By default, a qualified dependent name is a nontype
The compiler binds dependent names when a template is instantiated. The compiler binds non-dependent names when a template is defined.
Dependent Name
A dependent name is a name that depends on the type or the value of a template parameter. For example:
A qualified dependent name such as T::x can be: * A nontype (object or function) * A type * A template By default, a qualified dependent name is a nontype
The compiler binds dependent names when a template is instantiated. The compiler binds non-dependent names when a template is defined.
Function Templates
override the template-generated code by providing special definitions for specific types.
template <class T> class stream { public: void f() { cout << "stream<T>::f()"<< endl ;} }; template <> class stream <char> { public: void f() { cout << "stream<char>::f()"<< endl ;} }; int main() { stream<int> si ; stream<char> sc ; si.f() ; sc.f() ; return 0 ; }
Output:
stream<T>::f() stream<char>::f()
possible to override the template-generated code by providing special definitions for specific types
template <class T> T max(T a, T b) { return a > b ? a : b ; } int main() { cout << max(10, 15) << endl ; cout << max('k', 's') << endl ; cout << max(10.1, 15.2) << endl ; cout << max("Aladdin", "Jasmine") << endl ; return 0 ; }
template <class T> T max(T a, T b) { return a > b ? a : b ; } // Specialization of max for char* template <> char* max(char* a, char* b) { return strcmp(a, b) > 0 ? a : b ; } int main() { cout << max(10, 15) << endl ; cout << max('k', 's') << endl ; cout << max(10.1, 15.2) << endl ; cout << max("Aladdin", "Jasmine") << endl ; return 0 ;
Each template class or function generated from a template has its own copies of any static variables or members.
template <class T> class X { public: static T s ; }; int main() { X <int> xi ; X <char*> xc ; }
X <int> has a static data member of type int X <char*> has a static data member s of type char*.
and a global function and a member function of another class (possibly a template class) and class (possible template class).
Examples
template <class T> class aRectangle{ T x; T y; public: aRectangle() {} aRectangle(T a, T b) { x=a; y=b; } T add() { return x+y; } T multi() { return x*y; } }; int main() { aRectangle<int> a(2,5); cout << a.add()<<" " << a.multi(); }
Examples
template <class T> class aRectangle{ T x; T y; public: aRectangle() {} aRectangle(T a, T b) { x=a; y=b; } T add() { return x+y; } T multi() { return x*y; } }; int main() { aRectangle<int> a(2,5); cout << a.add()<<" " << a.multi(); aRectangle<string> a(hello,world); cout << a.add()<<" " << a.multi(); }
Examples
template <class T> class aRectangle{ T x; T y; public: aRectangle() {} aRectangle(T a, T b) { x=a; y=b; } T add() { return x+y; } T multi() { return x*y; } }; int main() { aRectangle<int> a(2,5); cout << a.add()<<" " << a.multi(); aRectangle<string> a(hello,world); cout << a.add()<<" " << a.multi(); }
Examples
template <class T> class aRectangle{ T x; T y; public: aRectangle() {} aRectangle(T a, T b) { x=a; y=b; } T add() { return x+y; } T multi() { return x*y; } }; int main() { aRectangle<int> a(2,5); cout << a.add()<<" " << a.multi(); aRectangle<string> a(hello,world); cout << a.add()<<" " << a.multi(); aRectangle<const int> a; cout << a.add()<<" " << a.multi(); }
Examples
template <class T> class aRectangle{ T x; T y; public: aRectangle() {} aRectangle(T a, T b) { x=a; y=b; } T add() { return x+y; } T multi() { return x*y; } }; int main() { aRectangle<int> a(2,5); cout << a.add()<<" " << a.multi(); aRectangle<string> a(hello,world); cout << a.add()<<" " << a.multi(); aRectangle<const int> a; cout << a.add()<<" " << a.multi(); }
Examples
template <class T> class aRectangle{ T x; T y; public: aRectangle() {} aRectangle(T a, T b) { x=a; y=b; } T add() { return x+y; } T multi() { return x*y; } }; int main() { aRectangle<int> a(2,5); cout << a.add()<<" " << a.multi(); aRectangle<string> a(hello,world); cout << a.add()<<" " << a.multi(); aRectangle<const int> a; cout << a.add()<<" " << a.multi(); aRectangle<int> x,y; aRectangle<aRectangle <int> > a; cout << a.add()<<" " << a.multi(); }
Non-type Templates
Non-type tempaltes parameters are the rvalue substitution type
Another nontype template parameter that has the right type A compile-time constant value of integer (or enumeration) type. The name of an external variable or function preceded by the built-in unary & operator The previous kind of argument but without a leading & operator is a valid argument for a nontype parameter of reference type A pointer to member constant
Examples
Non-type template parameters that are declared as arrays or functions are converted to pointers or pointers to functions, respectively.
template<int a[4]> class A { ....}; template<int f(int)> class B {... }; int i; int g(int) { return 0;} A<&i> x; B<&g> y; &i is deduced to int * &g is deduced to int (*)(int)
template <template<typename T, T*> class Buf> class Lexer { static char storage[5]; Buf<char, &Lexer<Buf>::storage> buf; };
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.
The format of namespaces is: namespace identifier { entities }
Examples
Examples
Examples
Namespace alias
Exceptions
Exceptions provide a way to react to exceptional circumstances (like runtime errors) in our program by transferring control to special functions called handlers.
Format: try{ statemets ....
Examples
Exceptions
We can chain multiple handlers (catch expressions), each one with a different parameter type. Only the handler that matches its type with the argument specified in the throw statement is executed. If we use an ellipsis (...) as the parameter of catch, that handler will catch any exception no matter what the type of the throw exception is.
Examples
try{ .......... } catch (int param){....} catch (char param){...} catch (...) {........}
Exception specifications
When declaring a function we can limit the exception type it might directly or indirectly throw by appending a throw suffix to the function declaration
float myfunction (char param) throw (int);
int myfunction (int param) throw(); // no exceptions allowed int myfunction (int param); // all exceptions allowed
Standard exceptions
C++ Standard library provides a base exceptions class This class has
usual default and copy constructors operators destructors additional virtual member function called what that returns a null-terminated character sequence (char *) and that can be overwritten in derived classes to contain some sort of description of the exception.
Examples
Standard Exceptions
try { int * myarray= new int[1000]; } catch (bad_alloc&) { cout << "Error allocating memory." << endl; }
Type Cast
Implicit
short a = 10; int b; b = a;
Explicit
short a = 10; int b; b = (int) a;
dynamic
dynamic_cast can be used only with pointers and references to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class. Run-Time Type Information (RTTI) to keep track of dynamic types.
Examples
class CBase { }; class CDerived: public CBase { }; CBase b; CBase* pb; CDerived d; CDerived* pd; pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived
Static cast
Type cast
double d=3.14159265; int i = static_cast<int>(d); perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived.
class CBase {}; class CDerived: public CBase {}; CBase * a = new CBase; CDerived * b = static_cast<CDerived*>(a);
reinterpret_cast
converts any pointer type to any other pointer type, even of unrelated classes.
class A {}; class B {}; A *a = new A; B *b = reinterpret_cast<B*>(a);
Type cast
const_cast
Type cast
typeid
typeid allows to check the type of an expression:
Open a File
Statement: open (filename, mode);
seekg() allow us to change the position of the get stream pointers seekg() allow us to change the position of the put stream pointers read() read from a file write() write to a file
References
The C++ Programming Language, by B. Stroustrup Programming -- Principles and Practice Using C++, by B. Stroustrup The Design and Evolution of C++, by B. Stroustrup Data Abstraction and problem solving with C++, by Frank M. Carrano C++ templates By David Vandevoorde, Nicolai M. Josuttis IBM(R) implementation of the C and C++ programming languages (http://publib.boulder.ibm.com/
infocenter/comphelp/v8v101/index.jsp)
References
The photos and some contents in this slide are also collected from Prof. Stephen A. Edwards' lecture slides The C++ Language Tutorial, by Juan Souli I have also taken help from several online sources which I found through Google search. However, I have lost track of them. I beg pardon for missing their names in the reference list.
Advance C++
Self Study
STL: Standard Template Library