Documente Academic
Documente Profesional
Documente Cultură
Jan 2013
PROGRAMMING IN C++
Jan 2013 OOP in C++ 2
Topics
Procedural Enhancements in C++ over C Classes Overloading Inheritance Type Casting Exceptions Templates
Jan 2013 OOP in C++ 3
TOPICS
Const-ness Reference Data Type Inline Functions Default Function Parameters Function Overloading & Resolution Dynamic Memory Allocation
Jan 2013
OOP in C++
const Quantifier
const qualifier transforms an object into a constant.
Example: const int capacity = 512; Any attempt to write a const object is an error Const object must be initialized.
References
A reference is an additional name / alias / synonym for an existing variable Declaration of a Reference
<type> & <name> = <existing variable>;
Examples of Declaration
int j = 5; int& i = j;
Jan 2013
OOP in C++
References
Wrong declarations
int& i; // must be initialized int& j = 5; // may be declared as const reference int& i = j+k; // may be declared as a const reference
Jan 2013
OOP in C++
References Do not ..
Cannot have an array of references No operator other than initialization are valid on a reference.
Cannot change the referent of the reference (Reference can not be assigned) Cannot take the address of the reference Cannot compare two references Cannot do arithmetic on references Cannot point to a reference
Returning a Reference
Returning a reference return value is not copied back may be faster than returning a value calling function can change returned object cannot be used with local variables
Jan 2013
OOP in C++
10
Returning a Reference
#include <iostream.h.> int& max(int& i, int& j) { if (i > j) return i; else return j; } int main(int, char *[]) { int x = 42, y = 7500, z; z = max(x, y) ; // z is now 7500 max(x, y) = 1 ; // y is now 1 cout << "x = " << x; cout << " y = " << y; cout << " z = " << z << "\n";
return 0;
}
Jan 2013 OOP in C++ 11
Jan 2013
OOP in C++
12
Macros
Macros are expanded at the places of their calls. Advantages:
Speed-wise efficient
Disadvantages:
Parameter passing mechanism is not robust and frequently leads to errors.
Type checking during parameter passing is not done
Typical Use:
Small code re-use
Jan 2013
OOP in C++
13
Inline Functions
Inline functions act like functions
Jan 2013
can be class members checking is performed can be overloaded obey normal parameter passing rules
Inline Notes
inline specification is only a recommendation. A recursive or a large function may not be inline. Unlike a non-inline function, an inline function must be defined in every text file where it is called. Inline functions must not have two different definitions.
May cause unexpected behavior if compiler does not chose to make the function inline.
Jan 2013 OOP in C++ 15
Wrong example:
#include ff.h ff(int i, float f = 0.0, char ch = a); //Error
Function Overloading
The same function name may be used in several definitions. Functions with the same name must have different number of formal parameters and/or different types of formal parameters. Function selection based on number and types of the actual parameters at the places of invocation. Function selection (Overload Resolution) is performed by the compiler Two functions having the same signature but different return types will result in a compilation error due to attempt to redeclare. Overloading allows static polymorphism
Jan 2013
OOP in C++
18
Overload Resolution
Steps to resolve overloaded functions with one parameter
Identify the set of candidate functions and the set of viable functions. Select the best viable function through (Order is important)
Jan 2013
Exact Match Promotion Standard type conversion User defined type conversion
OOP in C++ 19
Overload Resolution
Steps to resolve overloaded functions with one parameter
Example:
1. void f(); 2. void f(int); 3. void f(double, double = 3.4); 4. void f(char, char *); f(5.6) Candidate function: 2 & 3 Best function: 3
Jan 2013 OOP in C++ 20
Exact Match
lvalue-to-rvalue conversion
Most common
Array-to-pointer conversion
Definitions: int ar[10]; void f(int *a); Call: f(ar)
Function-to-pointer conversion
Definitions: int (*fp) (int); void f(int x, fp); int g(int); Call: f(5, g)
Qualification conversion
Converting pointer (only) to const pointer.
Jan 2013 OOP in C++ 21
Jan 2013
OOP in C++
22
Examples of Resolution
1. Promotion
enum e1 { a1, b1, c1 };
enum e2 { a2, b2, c2 = 0x80000000000 }; char *f(int); char *f(unsigned int); int main() { f(a1); //Which f?
3. Conversion Sequence
int arr[3]; void putValues(const int *); int main() { putValues(arr); }
f(a2); //Which f?
}
2. Standard Conversion
void print(int); void print(char *); void set (int *);
//Which set?
OOP in C++ 23
new/delete operators
In C++, the new and delete operators provide built-in language support for dynamic memory allocation and deallocation.
int *pI = new int; int *pI = new int(102); //new initializes!! int *pArr = new int[4*num]; Arrays generally cannot be initialized. const int *pI = new const int(100); Array of constant cannot be created. delete pI; delete [] pArr;
Matching operators
malloc-free new-delete new[] delete []
CLASS
Jan 2013 OOP in C++ 26
TOPICS
Class Members Constructor & Destructor Friends Static Members Struct & Union
Jan 2013
OOP in C++
27
Class
C++ Class is an implementation of type In C++, class is the only way to implement user defined data types. A C++ class contains data members/attributes to specify the state and operations/methods to specify the behavior. Thus, classes in C++ are responsible to offer needed data abstraction/encapsulation of Object Oriented Programming. C++ Classes also provide means (through access specifier) to enforce data hiding that separates implementation from interface.
Jan 2013
OOP in C++
28
Class
A Class is defined by class keyword. Each member in a class has an access specifier.
private these members are accessible inside the definition of the class. public these members are accessible everywhere.
Objects/instances of classes are to be created statically or dynamically. Members can be accesses by . operator on the object. The implicit this pointer holds the address of any object. this pointer is implicitly passed to methods.
Jan 2013
OOP in C++
29
A Simple Class
class Employee { public: void setName (const char *x) { name = strdup(x); } void setSalary (float y) { salary = y; } char *getName ( ) { return name; } float getSalary ( ) { return salary; } private: char }; *name; float salary; int main ()
{
Employee e1; Employee *e2; e2 = new Employee; e1.setName(Amit); e2->name = strdup(Ashis"); // Error e2.setSalary(29100); e2>setSalary(29100); } Re-look at void setName (const char *x) { name = strdup(x); } Whose name? void setName (const char *x) { this->name = strdup(x); }
OOP in C++ 30
Jan 2013
More on this
Type of this
Necessity of this to the programmer
X * const Distinguishing data member from non-member variable Explicit Use
class DoublyLinkedNode { DoublyLinkedNode *prev, *next; int data; public: void append(DoublyLinkedNode *x); } DoublyLinkedNode::append(DoublyLinkedNode *x) { next = x; x->prev = this; }
Jan 2013
OOP in C++
31
Constructor Functions
Constructor functions:
are member functions with the same name as the class are automatically called when an object is created, just after memory allocation
In case of auto/static variables, objects are created in the stack/static Store when their definition is encountered. Objects can be created in the Free store with a pointer storing the address.
Jan 2013
OOP in C++
32
Constructor Functions
Constructor functions:
Constructors also allocate additional memory space from the Free store (if) required for the object.
If users do not define any constructor then the compiler provides a default constructor.
Jan 2013 OOP in C++ 33
Jan 2013
OOP in C++
34
Destructor Functions
Destructor function:
is a member function named ~ <class-name>
String ( ) ) (e.g. ~
If destructor is not called then there could be memory leaks for objects which calls new in the constructor.
Jan 2013 OOP in C++ 35
Copy Constructor
Copy constructor is a special constructor which is used to initialize an object with another object of the same type. Copy constructor of class X takes an argument of type X &.
If the type of argument is X in stead of X&, an infinite loop results.
Jan 2013
OOP in C++
36
Copy Constructor
Situations where copy constructor is used:
Actual parameter passing in call-by-value Return Value passing Initializing an object with an object of the same type as shown in the following example.
Jan 2013
OOP in C++
37
public:
String(); String(const String&); // Copy Constructor String(const char *); ~ String(); int length(); int read(); void print(); private:
char *data;
int len; }
Jan 2013 OOP in C++ 38
data = NULL;
len = 0; }
char str[6];
strcpy(str, Hello);
String s2(str); String s3(s2); //Copy Constructor String s4 = new String(one); String s5 = new String(); delete s4; delete s5; }
OOP in C++ 39
Arrays
Using Default constructor while creating an array of objects
String arrayOfString[100]; // 100 objects created using the default constructor
Jan 2013
Object Layout
Simplistically, an object of a class must have enough space to store all members of that class. No space is required per object for storing function pointers for the methods declared in the class.
Methods on objects are translated by the compiler to C-like function calls by passing this pointer.
A String Object
data len
H e l l o \n
Jan 2013
OOP in C++
41
Members as Objects
Sometimes a class may have a data attribute which is an object of a class.
Employee class may have a member name whose type is String.
Jan 2013
OOP in C++
42
Members as Objects
Initialization of member objects can be arranged through the use of initializer lists
Initializer lists appear as a comma separated list
following a colon, after a constructors parameters and before the constructor definition where each list item is a named member object followed by its initializer value in parenthesis
Initializer lists are required for a member object that must be passed initial arguments for construction Initializer lists are required for const members and reference members
Jan 2013
OOP in C++
43
Methods should not return non-const reference or pointer to less accessible data
Defeats basic data hiding philosophy. May also lead to stunning consequences.
Jan 2013 OOP in C++ 44
Jan 2013
OOP in C++
45
Friend Functions
Friend functions are declared in one or more classes have access to the private members of those classes are distinguished from members with the keyword friend are not called with an invoking object of those classes
Jan 2013 OOP in C++ 46
String concat(char *left, String *right) { String both[strlen(left) + right->len + 1]; strcpy(both.data, left); strcat(both.data, right->data); return both; }
Jan 2013
OOP in C++
47
Jan 2013
OOP in C++
48
Jan 2013
OOP in C++
49
Static Data
A static data member is shared by all the objects of a class. Static data member may be public or private. Static data member must be initialized in a source file. It can be accessed
with the class-name followed by the scope resolution operator :: as a member of any object of the class
class X { public: static int count; // This is a declaration X() { count++; } } X::count = 0; //Definition & Initialization int main() { X a, b, c; printf(%d %d %d %d\n, X::count, a.count, b.count, c.count); }
Jan 2013
OOP in C++
50
this pointer is not passed to a static function must not refer to non-static members of its invoking object Philosophy of static members.
Jan 2013 OOP in C++ 52
The above code will not fail; The code in the following may fail however.
X1.cxx #include X.hxx int main() { X::g(); }
Data members are guaranteed to be initialized before any noninline function is called.
OOP in C++ 53
Jan 2013
OPERATOR OVERLOADING
Jan 2013 OOP in C++ 54
Overloading Operators
Semantics of an operator is represented by a function named operator op, where op is an operator symbol (+,*, - , [ ], etc. ) These functions can either be implemented as global friend functions and/or methods.
Jan 2013
OOP in C++
55
Overloading Operators
Example
Let + denote concatenation for Strings. s1 + s2 denote concatenation of strings s1 and s2. An expression of the form s1+s2 is converted to s1.operator+(s2) if there is a function named operator+ defined in the class String. s1+s2 is also equivalent to operator+(s1, s2) if a global function named operator+ is properly defined; typically such global functions are friends to the class String.
Jan 2013 OOP in C++ 56
Jan 2013
OOP in C++
57
Jan 2013
Bug: Self Assignment will cause problem Solution: Check the following condition and return if false. if (this != rhs) .
Jan 2013 OOP in C++ 59
Who deletes? The caller. What about the following use? Integer a(1), b(2), c(3), d(3); Integer e = a*b*c*d;
60
OOP in C++
If there is a need to define a copy constructor then there must be a need to overload assignment operator and vice-versa.
Jan 2013 OOP in C++ 61
Jan 2013
OOP in C++
62
Precedence or arity of an operator cannot be changed by overloading an operator. Conditional Operators like &&, ||, comma operator should not be overloaded.
Jan 2013
OOP in C++
63
Friends Vs Methods
Members are better in terms of restriction of scope which results in efficient searching for best function to resolve overloading. Members will not help if the left hand side of the operator is not of the class type.
String s1 = abc + s2; // may be wrong
In case of overloading stream operators, we need friend due to the reason stated above. Resolving in case of a conflict between friend and method.
Jan 2013 OOP in C++ 64
Retuning const ensures that overloaded * is compatible with the same operator on built-in types.
Jan 2013 OOP in C++ 65
Jan 2013
OOP in C++
66
Bit-wise const member functions may become unsafe. Conceptual const member function may need to change some bits of the object
mutable keyword.
Jan 2013 OOP in C++ 67
INHERITANCE
Jan 2013 OOP in C++ 68
Topics
Fundamentals of Inheritance protected Access Specifier Initialization
Virtual Functions
Jan 2013
OOP in C++
69
Reusability
Reuse an already tried and tested code Advantages:
Reduces cost & development time. Improves quality
Jan 2013
OOP in C++
70
The derived class may extend the state and behavior of the base class by adding more attributes and methods.
Jan 2013 OOP in C++ 71
In public inheritance, private members of the base class become private members of the derived class and public members of the base class become public members of the derived class However, private members of the base class are not directly accessible to the members in the derived class.
Jan 2013 OOP in C++ 72
OOP in C++
73
protected Members
private data members of the base class cannot be directly accessed by the methods of the derived class. However, it is important for the derived class to have more accessibility to the members of the base class than other classes or functions. If a member is protected then it is directly accessible to the methods of the derived class.
Jan 2013 OOP in C++ 74
Syntax of Inheritance
An example
class Employee { protected: float basic; long id; public: Employee(long id); float getSalary(); }; class Manager : public Employee { protected: Employee *supervised[10]; int numberOfPeopleManaged; public: Manager(Id, n); float getSalary(); void printSupervisedEmployeeId();
}
Jan 2013 OOP in C++ 75
Jan 2013
OOP in C++
76
Jan 2013
OOP in C++
77
Casting
Derived class pointer can be implicitly cast to a base class pointer
Manager m;
Employee *e = &m; // Employee *e = (Employee *)(&m);
Only base class part of the derived object can be seen through the base pointer.
e-> printSupervisedEmployeeId(); //error
Jan 2013
OOP in C++
79
Casting
A Base class pointer cannot be implicitly cast to a derived class pointer
Manager *pM; pM = e; //error pM = (Manager *)e; //ok Down casting may be dangerous
Jan 2013
OOP in C++
80
Jan 2013
OOP in C++
81
In the example however, it makes more sense to mean getSalary of the Manager class. We need a dynamic binding of e so that the type of e may be set at run time by pointer to the type of the actual object
Jan 2013
OOP in C++
82
Virtual Functions
In C++, dynamic binding is made possible only for pointer & reference data types and for methods that are declared as virtual in the base class. If a method is declared as virtual, it can be overridden in the derived class. If a method is not virtual and it is redefined in the derived class then the latter definition hides the former one.
Jan 2013 OOP in C++ 83
public:
int f(){ return 2; } virtual int g(){ return 3;} }; main() { Y a; int i, j , k, m; X *b = &a; i = b->f(); j = a.f(); k = b->g(); m = a.g();
public:
int f(){ return 4;} int g(){ return 6;} };
Output will be 2 4 6 6
class Y : public X {
protected: void f(); };
Jan 2013
OOP in C++
86
Abstract Class
Pure Virtual Function
A virtual function may be assigned to NULL meaning that this function is declared but not defined in a class. Definition of such a class is incomplete.
A class with one or more pure virtual function is called an abstract class.
Abstract class cannot be instantiated.
Abstract class define a contract or interface to be used by the user of the class library and to be implemented by the developer of the class library.
Jan 2013 OOP in C++ 87
Virtual Destructor
Constructors cannot be virtual For a base class which has been derived from, the destructor must be declared virtual. Occasionally we create a derived object and store it using a pointer to Base class such as
Base *pBase = new Derived(/*arguments*/);
If we destroy this object using delete pBase then two destructors need to be called.
If the destructor in the Base class is not declared virtual then the destructor of the Derived class will not be automatically called in this example.
Jan 2013 OOP in C++ 88
Jan 2013
OOP in C++
89
public:
0; }; class triangle : public Shape() { virtual double calculateArea() =
private:
Point centre; double radius; Circle(double x_centre, double y_centre, double r);, public: double calculateArea(); };
private:
Point a, b, c; Triangle(double x_a, double y_a, double x_b, double y_b, double x_c, double y_c); public: double calculateArea(); };
Jan 2013 OOP in C++
90
Inheritance: Benefits
Code Sharing/Reuse Consistency of Interface Construction of Software Components Rapid Prototyping Information Hiding
Jan 2013
OOP in C++
92
Inheritance: Cost
Execution Speed Program Size Message Passing Overhead Program Complexity
Jan 2013
OOP in C++
93
Inheritance: Limitations
operator= cannot be inherited
Can be used to assign objects of the same type only
Copy Constructor cannot be inherited Static members are inherited in a derived class
Static members cannot be virtual If you redefine a static member function, all other overloaded functions in the base class are hidden
Jan 2013 OOP in C++ 94
Inheritance Notes
Constructors cannot be virtual Calling a virtual function from within a constructor does not have the desired effect. The following code is buggy. Tell why.
void f(Base *b) {
b[0].f(); b[1].f(); } }
int main() {
Derived d[10]; f(d);
Derived is publicly derived from Base. Class Base has a virtual function f which is redefined in Derived.
Jan 2013 OOP in C++ 95
Is an Ostrich a Bird
Suppose there is a base class Bird
a virtual method fly returns altitude > 0.
Is a Circle an Ellipse?
Circle is a special type of ellipse. Let Circle be derived from Ellipse. Suppose that Ellipse has a method setSize(x,y). Also suppose that there is a function sample as defined below. sample (Ellipse &e) { e. setSize(10,20); . } If sample is called on a circle, strange things happen! Subset is not substitutable!!
Jan 2013 OOP in C++ 98
Multi-level Inheritance
Suppose that C is derived from B and B is derived from A. Suppose that a method, f, in A is virtual. If f is redefined in B then f is virtual even if the keyword virtual does not precede the declaration/definition in the derived class. It is advisable to explicitly write virtual in front of the definition of f in B as, otherwise, an implementer of C may think that f is not a virtual method.
Jan 2013
OOP in C++
100
A new class D is required to be derived from A later. f in D is different than A. Interfaces should not have implementation.
Jan 2013
OOP in C++
101
private Inheritance
If B is privately derived from A then private, protected and public members of A become private members of B. However, private members of A are not directly accessible to B. Thus, even if C is publicly derived from B then no member of A is accessible to C. Functions which may access members of A in B are
Methods of class B Friend functions of class B.
Jan 2013
OOP in C++
102
protected Inheritance
If B is protectedly derived from A then, protected and public members of A become protected members of B. However, private members of A remain private in B and are not directly accessible to B. Functions which may access members of A in B are
Methods of class B Friend functions of class B.
Set contains unique elements while List may contain duplicate elements.
Thus Set is not a List But a Set can use the code of the List class as a Set can be implemented in terms of a list. Users of the class Set should not have an access to the List behavior even to create further derived classes
Jan 2013 OOP in C++ 104
TYPE CASTING
Jan 2013 OOP in C++ 105
Type Casting
Why casting?
Casts are used to convert the type of an object, expression, function argument, or return value to that of another type.
Explicit conversions.
type is needed for an expression that cannot be obtained through an implicit conversion more than one standard conversion creates an ambiguous situation
Jan 2013 OOP in C++ 106
Type Casting
To perform a type cast, the compiler
allocates temporary storage Initializes temporary with value being cast
float f (int i,int j) { return (float ) i / j; } // compiler generates: float f (int i, int j) { float temp_I = i, temp_j = j; return temp_i / temp_j; }
Jan 2013 OOP in C++ 107
Ambiguities: Example
Overuse of such casting may lead to ambiguities as illustrated in the following example
/* ambig.cpp */ #include string.h class example { public: example(const char *) { } ; }; void f1 (const String & ) { } void f1 (const example & ) { } int main ( ) { // f1 (hello, world) ; is ambiguous f1 ((String) hello world ); f1 ((example) hello world ); // or provide void f1 (const char *) return 0; }
Jan 2013
OOP in C++
111
Ambiguity: Example
class B; class A { public: A (const B &); ... }; class B { public: operator A () const; }; void f(const A &); B b; f(b); //Error - Ambiguous
Jan 2013
OOP in C++
112
Jan 2013
OOP in C++
113
void operator-(const String &, const String &); int main ( ) { int fd; String filename = tmp/test; // cast filename to type const char * fd = open (filename, O_WRONLY | O_CREAT, 0666); write (fd, test, 4); close (fd); // not legal, since we can cast only to const char * // strcpy (filename, zbc); String name = Zaphod Beeblebrox; name Beeblebrox; // is now ambiguous. return 0 ; }
114
OOP in C++
Avoiding Ambiguities
const int max_string_length = 128; class String { public: String ( ) ; String (const String & ) ; String (const char *); ~ String ( ) ; String & operator = (const String & ); const char *as_char_pointer ( ) const; int length ( ) const; int read ( ); void print ( ) const; ... private: char text [max_string_length+1]; }; void operator-(const String &, const String &); int main ( ) { int fd; String filename = /tmp/test; // convert filename to type char * fd = open (filename.as_char_pointer ( ), O_WRONLY | O_CREAT, 0666); write (fd, test, 4); close (fd); // not legal // strcpy (filename.as_char_pointer ( ), zbc); String name = Zaphod Beeblebrox; name Beeblebrox; // is no longer ambiguous return 0; }
115
Jan 2013
OOP in C++
C++ casts
There are four cast operators in C++
const_cast static_cast reinterpret_cast dynamic_cast
Jan 2013
OOP in C++
117
Jan 2013
OOP in C++
118
const_cast operator
Syntax:
const_cast < type-id > ( expression )
The const_cast operator can be used to remove the const, volatile attribute(s) from a class. A pointer to any object type can be explicitly converted to a type that is identical except for the const, volatile qualifiers. Applying on pointers and references, the result will refer to the original object. The const_cast operator cannot be used to directly override a constant variable's constant status.
Jan 2013
OOP in C++
119
On the line containing the const_cast, the data type of the this pointer is const CCTest *. The const_cast operator changes the data type of the this pointer to CCTest *, allowing the member number to be modified. The cast lasts only for the remainder of the line on which it appears.
120
OOP in C++
Usage of const
The example of the previous slide is not the best usage of const.
The member number should be mutable instead.
When one has a const object and has to pass it to some function that takes a non-const parameter and it is known that the function does not modify that parameter then casting away const-ness is both useful and safe.
Jan 2013 OOP in C++ 121
Jan 2013
OOP in C++
122
static_cast operator
Syntax:
static_cast < type-id > ( expression )
The static_cast operator converts expression to the type of type-id based solely on the types present in the expression. static_cast has basically same power, meaning and restrictions as C-style cast. It cannot be used to convert a struct into an int or a double into a pointer.
Jan 2013
OOP in C++
123
static_cast operator
In general, a complete type can be converted to another type so long as some conversion sequence is provided by the language. may also use static_cast to convert any expression to a void, in which case the value of the expression is discarded. It cannot change the const-ness of an expression.
Jan 2013
OOP in C++
124
static_cast: Example
Example: class B { ... }; class D:public B { ... }; void f(B* pb, D* pd){ D* pd2 = static_cast<D*>(pb); // not safe, pb may point to just B B* pb2 = static_cast<B*>(pd); // safe conversion ... }.
The static_cast operator can be used for operations such as converting a base class pointer to a derived class pointer . Such conversions are not always safe since no runtime type check is made to ensure the safety of the conversion.For such conversions dynamic_cast should be used.
Jan 2013
OOP in C++
125
The old C-style casts let us cast from one incomplete type to another! static_cast does not let you do that.
Jan 2013
OOP in C++
126
reinterpret_cast operator
Syntax:
reinterpret_cast < type-id > ( expression )
The reinterpret_cast operator allows any pointer to be converted into any other pointer type. It also allows any integral type to be converted into any pointer type and vice versa. The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.
Jan 2013 OOP in C++ 127
reinterpret_cast operator
The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, non-portable. The reinterpret_cast operator cannot cast away the const, volatile attributes.
One practical use of reinterpret_cast is in a hash function, which maps a value to an index in such a way that two distinct values rarely end up with the same index.
Reinterpret_cast should rarely be used in a C++ program
Jan 2013
OOP in C++
128
reinterpret_cast: Example
Example #include <iostream> unsigned short Hash( void *p ){ // Returns a hash code based on an address unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); } int main(){ int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; }
The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.
Jan 2013
OOP in C++
129
Usage of casts
class A { public: virtual ~A(); }; class B : private virtual A { }; class C : public A { }; class D : public B, public C { }; A a1; B b1; C c1; Dd1; const A a2; const A& ra1 = a1; const A& ra2 = a2; char c;
A *pa = (A *)&ra1;
Use const_cast
B * pb = (B*)&c1;
Use reinterpret_cast
A *pa = (A*)&a2;
Cannot be expressed in a new-style cast.
Jan 2013
OOP in C++
130
Jan 2013
OOP in C++
131
type_info class
The type_info class describes type information generated within the program by the compiler. The entire definition of this class is implementation dependent but the following features of this class is standardized.
Objects of this class effectively store a pointer to a name for the type. The type_info class also stores an encoded value suitable for comparing two types for equality or collating order. The operators == and != are overloaded and can be used to compare for equality and inequality with other type_info objects, respectively.
Jan 2013
OOP in C++
132
type_info class
Features of type_info class (contd):
The name member function returns a const char* to a null-terminated string representing the humanreadable name of the type. The memory pointed to is cached and should never be directly deallocated.
Type information is generated for polymorphic classes only if the /GR (Enable Run-Time Type Information) compiler option is specified.
Jan 2013
OOP in C++
133
typeid operator
Syntax:
typeid( type-id ) OR typeid(expression)
The typeid operator allows the type of an object to be determined at run time. The result of typeid is a const type_info&. The typeid operator does a run-time check when applied to an l-value of a polymorphic class type, where the true type of the object cannot be determined by the static information provided. Such cases are: a reference/ Pointer
Jan 2013 OOP in C++ 134
typeid operator
When the operand of typeid is of a nonpolymorphic class type, the result is the type of the operand not the type of the underlying object. type-id may be used with operands of built-in types.
Jan 2013
OOP in C++
135
typeid:Example
The expression usually points to a polymorphic type (a class with virtual functions). The pointer must be dereferenced so that the object it points to is used. Without de-referencing the pointer, the result will be the type_info for the pointer, not pointee Example
#include <iostream> #include <typeinfo.h> class Base { public: virtual void vvfunc() {} } class Derived : public Base {};
Jan 2013 OOP in C++ 136
int main(){ Derived* pd = new Derived; Base* pb = pd; cout << typeid( pb ).name() << endl; //prints "class Base * cout << typeid( *pb ).name() << endl; //prints "class Derived" cout << typeid( pd ).name() << endl; //prints "class Derived *" cout << typeid( *pd ).name() << endl; //prints "class Derived" delete pd; }
dynamic_cast operator
Syntax:
dynamic_cast<typeid> (expression)
Example class B { ... }; class C : public B { ... }; class D : public C { ... }; void f(D* pd){ C* pc = dynamic_cast<C*>(pd); // ok: C is a direct base class, pc points to C subobject of pd B* pb = dynamic_cast<B*>(pd); // ok: B is an indirect base class , pb points to B subobject of pd ... }
The expression dynamic_cast<typeid>( expression) converts the operand expression to an object of type type-id. It is used for downcasting.
Jan 2013
OOP in C++
137
dynamic_cast: Example
Example: class B { ... }; class D : public B { ... }; void f(){ B* pb = new D; // unclear but ok B* pb2 = new B; D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D ... D* pd2 = dynamic_cast<D*>(pb2); // pb2 points to a B not a D the cast is bad so pd2 is NULL ... }
Jan 2013
OOP in C++
138
dynamic_cast
If dynamic_cast to a pointer type fails, the result of the dynamic_cast is null; if dynamic_cast to a reference type fails, an exception is thrown. dynamic_cast is performed at run-time. dynamic_cast can be used only for pointer or reference types to navigate a class hierarchy. The dynamic_cast operator can be used to cast from a derived class pointer to a base class pointer, cast a derived class pointer to another derived (sibling) class pointer, or cast a base class pointer to a derived class pointer. Each of these conversions may also be applied to references.
Jan 2013
OOP in C++
139
dynamic_cast
dynamic_cast operator cannot be used for built-in types. All of the derived-to-base conversions are performed using the static (compile-time) type information. These conversions may, therefore, be performed on both nonpolymorphic and polymorphic types. These conversions will produce the same result if they are converted using a static_cast. However, even these results may be wrong in the presence of multiple inheritance. dynamic_cast is strongly recommended to be applied on polymorphic types.
Jan 2013
OOP in C++
140
Cost of dynamic_cast
The pointer to the type_info object of a class is stored in the vtbl array of the class. Thus, the space cost for RTTI is an additional entry in each class vtbl plus the cost of storage for the type_info object for each class. Size of the objects do not increase for RTTI operations. Cost of RTTI at run time is similar to the cost of calling a virtual function; cost of calling a virtual function is the same as the cost of calling a function through a function pointer.
Jan 2013 OOP in C++ 141
EXCEPTIONS
Jan 2013 OOP in C++ 142
Topics
Basic Concept of Exceptions try-catch block in C++ Semantics of throw
Jan 2013
OOP in C++
143
by output parameter
normal and abnormal control flow tend to mix
Could return 1
Again program could ignore Might be a valid return value
Jan 2013
OOP in C++
146
Jan 2013
OOP in C++
147
}
DivideByZero(int d) { dividend = d; } }; int Calculator::divide(int i) throws DivideByZero { if (i ==0) throw DivideByZero(value); value /= i; return value; } Jan 2013
OOP in C++
149
Details of throw
Normal program control flow is halted
At the point where an exception is thrown
Jan 2013
OOP in C++
150
Jan 2013
OOP in C++
151
Exception Specifications
// can throw anything
void
Calculator::subtract (int i); // promises not to throw void Calculator::add (int i) throw (); // promises to only throw int void Calculator::divide (int i) throw (int);
Jan 2013
Make promises to the caller Allow stronger type checking enforced by the compiler By default, a function can throw anything it wants A throw clause in the signature
Limits what a function can throw A promise to the calling function Promises nothing will be thrown Comma separated
152
OOP in C++
Stack Frame
automatic variables parameters
g++ -s gives assembler output that can be used to deduce exact structure for a given platform In general, the overall structure is common A chunk of memory representing a function call Pushed on program call stack at runtime. Contains:
The frame pointer The return address for the call (i.e., where it was called from) Parameters passed to the function Automatic (stack) variables for the function
153
Jan 2013
OOP in C++
c.get_value ();
} catch (int) { return 1; } return 0; }
Note that parameters are initialized at frame creation Variables are not necessarily initialized at frame creation
May occur later in called function
i main
value_ argv
154
argc
OOP in C++
Jan 2013
c.get_value ();
} catch (int) { return 1; } return 0; }
i main
value_ argv
155
argc
OOP in C++
Jan 2013
Push a new stack frame No parameters or automatic variables for that specific function Params depend on function signature declaration Automatics depend on function body definition
return 0;
}
argc
OOP in C++
Jan 2013
{
if (i == 0) { throw i; } else { value_ /= i; } cout << value_; }
Jan 2013 OOP in C++
Calculator:: Calculator()
this
i
main
value_
argv
157
argc
Return from function Calculator::Calculator ( ) Pop the stack frame, return to previous
value_ /= i;
} cout << value_; }
Jan 2013
main
value_
argv
158
argc
OOP in C++
Push a new stack frame Contains parameters this and i Copy address of current instance into this Copy value 0 into i
this i main argc argv
159
cout <<
c.get_value (); } catch (int) { return 1; } return 0; }
Jan 2013
i value_
OOP in C++
void Calculator::divide (int i) throw (int) { if (i == 0) { throw i; } else { value_ /= i; } cout << value_; }
this c
i value_ argv
160
argc
Jan 2013 OOP in C++
Thrown exception unwinds call stack Notice control skips over cout statement to end Pop the stack frame, return to previous Return from function void Calculator::divide ( )
i main
value_ argv
161
argc
OOP in C++
Jan 2013
i main
value_ argv
162
argc
Jan 2013 OOP in C++
More on catch
try { // can throw an exception } catch (Derived &d) { // ... }
OOP in C++
Jan 2013
More correct
Jan 2013
OOP in C++
TEMPLATES
Jan 2013 OOP in C++ 165
What is a Template?
Templates are specifications of a collection of functions or classes which are parameterized by types. Examples:
Function search, min etc..
The basic algorithms in these functions are the same independent of types. But, we need to write different versions of these functions for strong type checking in C++.
Template instantiation
Jan 2013 OOP in C++ 167
Parameterized Functions
A function template
describes how a function should be built supplies the definition of the function using some arbitrary types, (as place holders), a parameterized definition can be considered the definition for a set of overloaded versions of a function is identified by the keyword template followed by parameter identifiers enclosed between < and > delimiters noting they are
Jan 2013
OOP in C++
typename
The key words class and typename have almost the same meaning in a template parameter typename is also used to tell the compiler that an expression is a type expression
template <class T> f (T x) { T::name * p; // Is this a pointer declaration or multiplication? } template <class T> f (T x) { typename T::name * p; // Is this a pointer declaration or multiplication? }
Jan 2013 OOP in C++ 170
Jan 2013
OOP in C++
171
If the same template parameter are found for more than one function argument, template argument deduction from each function argument must be the same
Jan 2013
OOP in C++
172
Jan 2013
OOP in C++
174
Jan 2013
OOP in C++
175
Jan 2013
OOP in C++
176
Parameterized Class
A class template describes how a class should be built Supplies the class description and the definition of the member functions using some arbitrary type name, (as a place holder). is a parameterized type with parameterized member functions
Jan 2013
OOP in C++
177
Parameterized Class
can be considered the definition for an unbounded set of class types is identified by the keyword template followed by parameter identifiers enclosed between < and > delimiters noting they are class, (i.e. type), parameters is often used for container classes
Jan 2013
OOP in C++
178
Parameter Requirements
Parameter Types may be of any type, (including user defined types) may be parameterized types, (i.e. templates)
MUST
support the methods used by the template functions: what are the required constructors ? the required operator functions ? What are the necessary defining operations ?
OOP in C++ 179
Jan 2013
A template definition can refer to a class template or its instances but a n non-template can only refer to template instances.
Jan 2013 OOP in C++ 180
A static data member in a class template is itself a template. Each static data member instantiation corresponds to a class template instantiation.
Jan 2013 OOP in C++ 181
Separation Model
Use keyword export in front of definition.
Jan 2013
Template specialization
Allows to make specific implementation when pattern is of determined type. The syntax is
template<> class XXX<Type> {..}
No member is inherited from the generic template to specialized one. So, must define ALL members equating them to specialization Class templates can be partially specialized too.
A totally disjoint template that the compiler gives a priority while instantiation.
Jan 2013 OOP in C++ 183
Jan 2013
OOP in C++
185
Jan 2013
OOP in C++
Jan 2013
OOP in C++
187
Inheritance vs Templates
Inheritance : helps in reusing object code Templates : helps in reusing source-code
object code size of template code is therefore much less.
Compiler view
Constructor of objects containing virtual functions must initialize the vptr table. Template class knows the type of the class at compile-time instead of having to determine it at run-time (as in case of virtual function usage)
Jan 2013
OOP in C++
188
Jan 2013
OOP in C++
189
Requirement:
cin and ifstream both derived from basic_istream The common base class basic_istream has suitable interface rdbuf.
Merely requires that the passed objects to have suitable interface (such as member function named rdbuf(). )
Jan 2013
Both Methods solve the current problem. But templates provide extensibility.
Other streams can be provided with rdbuf() interface. Other streams cannot be guaranteed to be derived from the same base class
190
OOP in C++
Another Example
A collection of classes is required for
Stack: for ints , strings, floats etc.
Has operations: push, pop, length of stack. Has features : move, comfort etc each move in diff ways. Each provide different level of comfort.
Analyze if the type being manipulated has any affect on the behavior of class .
If type does not affect the behavior, use templates If type affects the behavior, use virtual functions (inheritance)
Jan 2013 OOP in C++ 191
Thank You