Sie sind auf Seite 1von 63

Programming in C++

Slide: 1 Matangini Chattopadhyay


Topics

Procedural Enhancements in C++ over C


Classes
Overloading

Slide: 2 Matangini Chattopadhyay


Object Oriented Programming in
C++
Major Procedural Feature Enhancements in C++
Over ANSI C

Slide: 3 Matangini Chattopadhyay


TOPICS

Const-ness
Reference Data Type
Inline Functions
Default Function Parameters
Function Overloading & Resolution
Dynamic Memory Allocation

Slide: 4 Matangini Chattopadhyay


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.
Pointer to a non-constant object can not point to a
const object;
const double d = 5.6;
double *p = &d; //error
Pointer to a constant object vs. constant pointer to
an object.
const double * pConstantObject;
double * const *pConstantPointer;

Slide: 5 Matangini Chattopadhyay


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;

Slide: 6 Matangini Chattopadhyay


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
Often used as function parameters :
called function can change actual argument
faster than call-by-value for large objects

Slide: 7 Matangini Chattopadhyay


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
All operations on a reference actually work on
the referent.
Slide: 8 Matangini Chattopadhyay
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

Slide: 9 Matangini Chattopadhyay


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;
}

Slide: 10 Matangini Chattopadhyay


Pointers vs. References

Pointers can point to NULL whereas


References cannot. There is nothing
defined as NULL Reference.
Pointers can point to different variables at
different times whereas for a reference, its
referent is fixed.
References make code faster since, unlike
pointers, checks for NULL are not required.
Reference refers to an address but does
not store that address. Pointer does.

Slide: 11 Matangini Chattopadhyay


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

Code size tend to increase

Typical Use:
Small code re-use
Slide: 12 Matangini Chattopadhyay
Inline Functions
Inline functions act like functions
They can be class members
Type checking is performed
They can be overloaded
They obey normal parameter passing rules
But they are implemented like macros
Code is substituted inline, not called
Use is faster than calling a function
Use may take more space
They are defined in .h files, not in .c/.cxx files

Slide: 13 Matangini Chattopadhyay


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.

Slide: 14 Matangini Chattopadhyay


Default Function Arguments
Default arguments are appropriate argument
value of a parameter for a majority of cases.
Default arguments can be supplied to one or
more parameters.
Default arguments may be expressions also.
All parameters to the right of a parameter with
default argument must have default arguments.
Default arguments cannot be re-defined.
Default parameters should be supplied only in a
header file and not in the definition of a
function.

Slide: 15 Matangini Chattopadhyay


Default Arguments: Example
Following are some examples of functions with
default arguments.
Void ff (int, float = 0.0, char *); // Error
Void ff2(int, float = 0, char *=NULL); // OK
Void ff2(int, float = 1, char *= NULL); // Error Redefinition
Assume that ff.h contains the following declaration
ff(int, float, char = a);
Wrong example:
#include ff.h
ff(int i, float f = 0.0, char ch = a); //Error
However, the following are correct.
#include <ff.h>
ff(int i, float f = 0.0, char ch); //OK
ff(int i = 0, float f, char ch); //OK

Slide: 16 Matangini Chattopadhyay


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 re-declare.
Overloading allows static polymorphism

Slide: 17 Matangini Chattopadhyay


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)
Exact Match
Promotion
Standard type conversion
User defined type conversion

Slide: 18 Matangini Chattopadhyay


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

Slide: 19 Matangini Chattopadhyay


Promotion & Conversion
Examples of Promotion
char to int; float to double
enum to int/long/unsigned int/
bool to int
Examples of Standard Conversion
integral conversion
floating point conversion
floating point Integral conversion
The above 3 may be dangerous!
pointer conversion
bool conversion

Slide: 20 Matangini Chattopadhyay


Examples of Resolution
1. Promotion 3. Conversion Sequence
enum e1 { a1, b1, c1 }; int arr[3];
enum e2 { a2, b2, c2 = 0x80000000000 }; void putValues(const int *);
int main()
char *f(int); char *f(unsigned int);
{
int main()
{ putValues(arr);
f(a1); //Which f? }
f(a2); //Which f?
}

2. Standard Conversion
void print(int); void print(char *);
void set (int *);
void set (const char *);

int main()
{
print (0); //Which print?
set (0); //Which set?
}

Slide: 21 Matangini Chattopadhyay


new/delete operators
In C++, the new and delete operators provide built-in
language support for dynamic memory allocation and de-
allocation.
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;
new is polymorphic
new does more than malloc!

Slide: 22 Matangini Chattopadhyay


new/delete & malloc/free

All C++ implementations also permit use of malloc


and free routines.
Do not free the space created by new.
Do not delete the space created by malloc
Results of the above two operations is memory corruption.
Matching operators
malloc-free
new-delete
new[] delete []
It is a good idea to use only new and delete in a C++
program.

Slide: 23 Matangini Chattopadhyay


Object Oriented Programming in
C++
Classes

Slide: 24 Matangini Chattopadhyay


TOPICS

Class Members
Constructor & Destructor
Friends
Static Members
Struct & Union

Slide: 25 Matangini Chattopadhyay


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.

Slide: 26 Matangini Chattopadhyay


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.

Slide: 27 Matangini Chattopadhyay


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); }

Slide: 28 Matangini Chattopadhyay


More on this
Type of this
X * const
Necessity of this to the programmer
Distinguishing data member from non-member
variable
Explicit Use
class DoublyLinkedNode DoublyLinkedNode::append(DoublyLinkedNode *x)
{ {
DoublyLinkedNode *prev, *next; next = x;
int data; x->prev = this;
public: }
void append(DoublyLinkedNode *x);
}

Slide: 29 Matangini Chattopadhyay


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.
allow the class to initialise the state of an object
Constructors also allocate additional memory space from the
Free store (if) required for the object.
must not have any return type even void
Default constructors are those constructors which either do
not have an argument or have default arguments for all
parameters.
If users do not define any constructor then the compiler
provides a default constructor.

Slide: 30 Matangini Chattopadhyay


Additional Constructor Functions
Constructor function can be overloaded
Constructor functions can be directly
called to create anonymous objects
Calling a constructor from a constructor
does not have the desired effect.
If there is at least one definition of
constructor but no default constructor
then the following statements are
incorrect
X a;
X *pX = new X();

Slide: 31 Matangini Chattopadhyay


Destructor Functions
Destructor function:
is a member function named ~ <class-name> (e.g. ~
String ( ) )
is automatically called when an object is destroyed, just
before memory is freed
For auto variables when the variable goes out of scope
For objects created in the Free store, destructor is called after
delete or delete[] is explicitly invoked by the programmer.
must not have any argument or return value

If destructor is not called then there could be


memory leaks for objects which calls new in the
constructor.

Slide: 32 Matangini Chattopadhyay


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.
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.
The compiler provides a default implementation of the
copy constructor.

Slide: 33 Matangini Chattopadhyay


A Sample Class : String
class String {
public:
String();
String(const String&); // Copy Constructor
String(const char *);
~ String();
int length();
int read();
void print();
private:
char *data;
int len;
}

Slide: 34 Matangini Chattopadhyay


Class String::Constructor & Destructor
String::String() int main()
{ {
data = NULL; String s1; //default constructor
len = 0; String s11(); //Error
} String s1(test);
char str[6];
String::String(const char *s) strcpy(str, Hello);
{ String s2(str);
data = new char[strlen(s)+1];
String s3(s2); //Copy Constructor
len = strlen(s);
String s4 = new String(one);
strcpy(data, s);
String s5 = new String();
}
delete s4;
void ~String() delete s5;
{ }
if (data != NULL)
delete [] data;
}

Slide: 35 Matangini Chattopadhyay


Arrays
Using Default constructor while creating
an array of objects
String arrayOfString[100]; // 100 objects created using the default
constructor

Using specialized constructor while


creating an array of objects.
String arrayOfString[2] = { String(abc), String(def) };

Using different constructor for creating


array objects dynamically.
String *pArrayOfString[2] = { new String(abc), new String(def) };

Slide: 36 Matangini Chattopadhyay


Object Layout
Simplistically, an object
of a class must have A String Object
enough space to store
all members of that
class.
data
No space is required per
object for storing len
function pointers for the
methods declared in the
class.
Methods on objects are H e l l o \n
translated by the compiler
to C-like function calls by
passing this pointer.

Slide: 37 Matangini Chattopadhyay


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.
When an Employee object is initialized then name must also be
initialized.
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

Slide: 38 Matangini Chattopadhyay


Class Member: Notes
It is always a good idea to define data members as
private.
Composition through objects are preferred over
Composition through pointers
Saves time and life cycle management
Not possible in a number of situations
Contained object is shared by many containers.
Contained object may not always be present.

Methods should not return non-const reference or


pointer to less accessible data
Defeats basic data hiding philosophy.
May also lead to stunning consequences.

Slide: 39 Matangini Chattopadhyay


Const Member Functions
Constant Member Functions class X {
private:
are not allowed to change int ipriv;
the state of the object on public:

which they are invoked. int ipub;


int f() const;

Const Functions are };

declared with keyword int X::f() const


const following member {
int temp;
function parameter list. temp = ipriv + ipub; //accessing members OK

const must also be present ipriv += temp; // cannot modify any member
ipub -= temp; // cannot modify any member
at the definition. }

Type of this pointer passed


to a const function is
const X* const this

Slide: 40 Matangini Chattopadhyay


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

Slide: 41 Matangini Chattopadhyay


Friend Functions: Example
class String { String concat(String *left, String *right)
public : {
String(); String both[left->len + right->len + 1];
String(const char *);
strcpy(both.data, left->data);
String(int len);
strcat(both.data, right-> data) ;
friend String concat(String *, String *)
return both;
friend String concat(String *, char *);
friend String concat(char *, String *); }

private :
char *data; String concat(char *left, String *right)
int len; {
} ; String both[strlen(left) + right->len + 1];
strcpy(both.data, left);
String::String(int len)
strcat(both.data, right->data);
{
return both;
this->len = len;
}
data = new char[len+1];
data[len] = \0;
}

Slide: 42 Matangini Chattopadhyay


Friends of More Than One class
class Matrix; // Forward declaration to make Vector prod(Matrix *pM, Vector *pV)
// declaration of crossprod legal {
class Vector { int V(pM->m);
public :
for (i = 0; i < pM->m; i++)
void Vector(int n) ;
for (j = 0; j < pM->n; j++)
friend Vector prod(Matrix *pM, Vector *pV);
int elements[10] ; {
int n; v[i] += pm->elements[i][j]*
}; pV->elements[i];
}
class Matrix {
}
public :
void Matrix(int m, int n) ;
friend Vector prod(Matrix *pM, Vector *pV);
private :
int elements[10][10];
int m, n;
};

Slide: 43 Matangini Chattopadhyay


Friend Members & Class
Member of a different class class Matrix;
class Vector {
may be a friend function.
public:
A class may be declared as void Vector(int n);
a friend implying all Vector prod(Matrix *pM);
member functions of that int elements[10];

class are friends. int n;


} ;
Friend-ship is neither class Matrix {
commutative nor transitive. public:

Friends tend to break data void Matrix(int m, int n);


friend Vector Vector::prod(Matrix *pM);
hiding.
private:
It is best to avoid friend in int elements[10][10];
an ideal OO Design. int m, n;
} ;

Slide: 44 Matangini Chattopadhyay


Static Data
A static data member is class X {
shared by all the objects of public:
a class. static int count; // This is a declaration
X() { count++; }
Static data member may be }
public or private.
X::count = 0; //Definition & Initialization
Static data member must be int main()
initialized in a source file. {
X a, b, c;
It can be accessed printf(%d %d %d %d\n, X::count, a.count,

with the class-name b.count, c.count);

followed by the scope }

resolution operator ::
as a member of any object The output will be 3 3 3 3
of the class

Slide: 45 Matangini Chattopadhyay


Static Data: A List
void ListNode::print()
class ListNode
{
{
ListNode *x;
public:
x = ListNode::first;
static ListNode *first;
while (x != NULL)
private:
{
ListNode *next;
printf(%d , x->data);
int data;
x = x->next;
public:
}
ListNode(int x);
printf(\n);
print();
}
}
int main()
List Node *ListNode::first = NULL;
{
ListNode x(5);
ListNode::ListNode(int x)
ListNode x(7);
{
ListNode x(8);
data = x;
x.print();
next = NULL;
}
if (first == NULL)
first = this;
else The output will be 8 7 5
{
next = first;
first = this;
}
}

Slide: 46 Matangini Chattopadhyay


Static Member Functions

Static member functions


May be invoked
with the class-name::
class_name::static_function (args)
as part of any objects interface
any_object.static_function (args);

this pointer is not passed to a static function


must not refer to non-static members of its
invoking object
Philosophy of static members.

Slide: 47 Matangini Chattopadhyay


Static Members in Inline Functions
X.cxx
Not Safe #include X.hxx
void X::f()
X.hxx {
Class X X::g();
{ }

public: The above code will not fail; The


static void f(); code in the following may fail
however.
static String g();
X1.cxx
private:
#include X.hxx
static String s;
int main()
} {
inline String X::g() X::g();
{ }

// do some operation on s Data members are


return s; guaranteed to be initialized
} before any non-inline
function is called.

Slide: 48 Matangini Chattopadhyay


Object Oriented Programming in
C++
Operator Overloading

Slide: 49 Matangini Chattopadhyay


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.
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.

Slide: 50 Matangini Chattopadhyay


Example of overloading operator +
/ * string .h * / String operator+(char * text)
const int max_string_length = 128 ; {
class String { char *save = new char[len+1];
public : strcpy(save, data);
String opertator + (char *text) ; data = new char[len +strlen(text) + 1];
String opertator + (String &s1) ; strcpy(data, save);
String (char *data); stcat(data, text);
String () { data = NULL; len = 0; } delete[]save;
private : return (*this);
char *data; }
int len;
};

Slide: 51 Matangini Chattopadhyay


Overloading Assignment Operator
String & String: :operator=( char *rhs) String String: :operator=( String &rhs)
{ {

data = new char [strlen(rhs) + 1]; data = new char [rhs.len + 1];

strcpy ( data, rhs); strcpy ( data, rhs.data);


return *this ;
return *this ;
}
}
Bug:
Bug: The following
assignment cannot be
Memory Leak as previous made
data of this is not deleted. String x(abc), y(def), z(ghi);
x = y = z;
(x.operator=((y).operator=(z)));
.
Solution
.
. Change the return type
to String &

Slide: 52 Matangini Chattopadhyay


Overloading Assignment Operator

String & String: :operator (String &rhs)


{
delete [] data;
data = new char [rhs.len + 1];
strcpy ( data, rhs.data);
return *this ;
}

Bug:
Self Assignment will cause problem
Solution:
Check the following condition and return if false.
if (this != rhs) .

Slide: 53 Matangini Chattopadhyay


Reference & Overloading

Suppose that we have a class Integer & operator*(Integer &lhs, Integer


&rhs)
Integer which has a private
{
data member as int. The
Integer *result = new Integer( lhs.data *
following function is declared rhd.data);
as a friend of Integer. return *result;
Integer & operator*(Integer &lhs, Integer }
&rhs)
{
Who deletes?
Integer result = lhs.data * rhd.data;
return result; The caller.
}
What about the following use?
Integer a(1), b(2), c(3), d(3);
Problem: Returning reference
to a local object. The code Integer e =
wont work. a*b*c*d;

Slide: 54 Matangini Chattopadhyay


More On = Operator Overloading
There is a system defined implementation of
assignment operator. In absence of user
defined assignment operator function,
systems function is used.
System defined function makes a shallow copy.
Some times shallow copying may be dangerous
If the constructor uses new, assignment
operator may have to be overloaded.
If there is a need to define a copy constructor
then there must be a need to overload
assignment operator and vice-versa.

Slide: 55 Matangini Chattopadhyay


Overloading Unary Operators
Typically methods implementing unary
operators will not have any argument.
Exceptions:
post increment and post decrement operators.
As there are two operators with the same symbol
++, the name of the function is the the same.
Prototype for pre increment function:
void operator ++ ( );

Prototype for post increment function:


void operator ++ (int a);

Slide: 56 Matangini Chattopadhyay


Operator Overloading Facts

Some operators can not be implemented


as global(friend) functions.
=, [] etc.

Some Operators cannot be overloaded


::,.*.?:,., sizeof() etc.

Precedence or arity of an operator cannot


be changed by overloading an operator.
Conditional Operators like &&, ||, comma
operator should not be overloaded.
Slide: 57 Matangini Chattopadhyay
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.

Slide: 58 Matangini Chattopadhyay


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;
}

Slide: 59 Matangini Chattopadhyay


Casting to User Defined Type
Constructors help
The following statement is not an error even
when an appropriate assignment operator is
not defined but an appropriate constructor is
defined (which constructor?)
String s1; s1 = example;
The assignment statement is converted to the
following
s1 = String(example);
Lots of temporary objects are created.
Even the following statement is correct:
s1 = s2 + abc + def;

Slide: 60 Matangini Chattopadhyay


Ambiguities: Example

Overuse of such f1 (const String & )


{
casting may lead to }
ambiguities as void
illustrated in the f1 (const example & )
following example {
}
/* ambig.cpp */ int
#include string.h main ( )
class example { {
public: // f1 (hello, world) ; is ambiguous
example(const char *) { } ; f1 ((String) hello world );
}; f1 ((example) hello world );
void // or provide void f1 (const char *)
return 0;
}

Slide: 61 Matangini Chattopadhyay


Ambiguity: Example
class B;
Which one to use for
class A {
public:
casting?
A (const B &); Constructor in A OR
...
}; Cast Operator in B

class B {
public:
operator A () const;
};
void f(const A &);

B b;
f(b); //Error - Ambiguous

Slide: 62 Matangini Chattopadhyay


Casting Pointers & References
Casting a value:
float f_var = 3.14;
cout << (int) f_var;
creates a temporary object
does not violate data encapsulation
Casting a pointer or reference
cout << *(( int *) &f_var);
cout << (int &) f_var;
Re-interprets representation of object
Violates data encapsulation

Slide: 63 Matangini Chattopadhyay

Das könnte Ihnen auch gefallen