Introductory Course on C++

download Introductory Course on C++

of 209

Transcript of Introductory Course on C++

  • 8/4/2019 Introductory Course on C++

    1/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 1

    The C++ Programming Language

    Introductory Course

    Covers basic concepts and elements of C++ Requires knowledge of fundamental concepts of object-oriented and procedural programming

    Does not require knowledge of C

    Dr. Dragan Miliev

    Ass. Professor, University of [email protected], www.rcub.bg.ac.yu/~dmilicev

  • 8/4/2019 Introductory Course on C++

    2/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 2

    Outline

    Part I: Introduction

    Part II: General Issues

    Part III: Procedural Elements

    Part IV: Classes

    Part V: Derived Classes and PolymorphismPart VI: Conclusions

  • 8/4/2019 Introductory Course on C++

    3/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 3

    Part I: Introduction

    About this Course

    Getting Started

  • 8/4/2019 Introductory Course on C++

    4/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 4

    Chapter 1: About this Course

    Subject and Objectives

    Prerequisites

    Resources

  • 8/4/2019 Introductory Course on C++

    5/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 5/209

    Subject and Objectives

    Subject: Basic concepts of the C++ programming language

    Implementation of procedural and OO concepts in C++

    Style guidelines for programming in C++

    General applicability: not oriented to any library,framework, or tool

    Objectives: Get familiar with the basic concepts of C++

    Get ready to read, understand, and write C++programs

  • 8/4/2019 Introductory Course on C++

    6/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 6/209

    Prerequisites

    Understanding of fundamental concepts of theprocedural programming paradigm: Type and variable, pointer/reference

    Declaration, expression, statement, condition, loop

    Subprogram (procedure and function), argument(formal and actual), invocation, recursion

    Understanding of fundamental concepts of theobject-oriented programming paradigm:

    Classes, objects, and references to objects Attributes and structural relationships

    Operations, constructors/destructors, and encapsulation

    Inheritance (generalization/specialization, substitution)and polymorphism

  • 8/4/2019 Introductory Course on C++

    7/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 7/209

    Resources

    Books on OO programming and C++: B. Stroustrup, The C++ Programming Language, 2nd

    ed., Addison-Wesley, 1993

    M. A. Ellis, B. Stroustrup, The Annotated C++

    Reference Manual, Addison-Wesley, 1990

    Discussion with Dr. Miliev:[email protected]/~dmilicev

    Other books on OO programming, C++ and otherprogramming languages, and design patterns

  • 8/4/2019 Introductory Course on C++

    8/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 8

    Chapter 2: Getting Started

    About C++

    C/C++ Design Principles

    A Simple C++ Program

  • 8/4/2019 Introductory Course on C++

    9/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 9/209

    About C++

    C++ is a standard, object-oriented, common-purposeprogramming language

    C++ is vertically compatible with C: all C programs can becompiled with C++ compilers

    However, C++ is a language of a new generation and ofdifferent paradigm than C! The difference between C andC++ is much bigger (conceptual) than between C++ andJava, for example

    C++ supports all fundamental OO concepts, but alsoallows non-OO parts or entire programs

    C++ is a tool that helps to make good OO programs, notprevents from making bad OO or procedural programs

    C++ is a means of expressing OO design of software

  • 8/4/2019 Introductory Course on C++

    10/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 10/209

    C/C++ Design Principles

    C++ is vertically compatible with C: all C programs can becompiled with C++ compilers

    Efficiency of implementation: the compiled code has almostthe same efficiency as the equivalent hand-writtenassembly code

    Extensive compile-time checkingNo runtime checking

    Static typing, strong, but not exclusive typing (conversionsare allowed)

    Uniform treatment of built-in (primitive) and user-defined(classes) types of objects

    Alignment of the sizes of the built-in types to the machinearchitecture; consequently, the sizes of the built-in typesare not standard

  • 8/4/2019 Introductory Course on C++

    11/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 11/209

    Counter

    3

    create(3)

    A Simple C++ Program

    Task:Write a class that abstracts a counter that can beinitialized to the given value, incremented, andasked for the current value.

    Write a program that creates several counters,increments them independently, and writes theirvalues at the standard output.

    val()?

    Counter

    - counter : int

    + Counter(int)+ inc()+ val() : int

    4

    inc()

    5inc()

  • 8/4/2019 Introductory Course on C++

    12/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 12/209

    A Simple C++ Program

    // A simple C++ program#include

    class Counter {

    public:

    Counter (int initVal);

    voidinc ();

    int val();

    private:

    int counter;};

    Counter::Counter (int initVal) {

    counter = initVal;}

    Comment: from // to end of line

    Include declarations of librarian elements forstandard input/output operations

    Start of definition of class Counter

    Start of the section of public class members

    Declaration of a constructor with aninteger argument

    Declaration of an operation (member function)without arguments and with no resultDeclaration of an operation (member function)without arguments and with an integer result

    Start of the section of private class members

    Declaration of an integer attribute (data member)

    End of definition of class CounterDefinition of the constructor of class Counter

    Start of the method definition: a compoundstatement (block)

    Access to the member of the object being constructed

    Assignment expression as a statementEnd of the method definition (block)

  • 8/4/2019 Introductory Course on C++

    13/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 13/209

    A Simple C++ Program

    // A simple C++ program, continued:voidCounter::inc () {counter = counter + 1;

    }

    int Counter::val () {

    return counter;}

    voidmain () {Counter* c1 = new Counter(0);Counter* c2 = new Counter(3);

    c1->inc(); c2->inc();cout

  • 8/4/2019 Introductory Course on C++

    14/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 14

    Part II: General Issues

    Lexical Elements

    Types and Conversions

    Built-in Types

    Declarations and Scopes

    Object LifetimesProgram Structure

  • 8/4/2019 Introductory Course on C++

    15/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 15

    Chapter 3: Lexical Elements

    Tokens

    Comments

    Identifiers

    Literals

  • 8/4/2019 Introductory Course on C++

    16/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 16/209

    Tokens

    C++ is case-sensitiveWhite spaces: blanks, tabs, new lines, new pages

    White spaces separate tokens and do not nave any othermeaning for the compiler; these are equivalent:

    if (acharchar c1 = 0;for (int i=0; iint->char...

    }

    Variants ofchar, which have the same memory size aschar, but treated differently when converted into int: signed char: the integer value may be negative

    unsigned char: the integer value is always non-negative

  • 8/4/2019 Introductory Course on C++

    29/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 29/209

    Boolean Type

    Newer version of C++ allow a Boolean type boolThe objects ofbool may have one of two symbolic values:false and true

    A Boolean object may be implicitly converted into an

    integer: false is converted to 0, and true to 1An integer object may be implicitly converted into a bool:0 is converted to false, and any non-zero value to true

    bool flag = false;

    ...

    flag = true;...

    if (flag) ...

  • 8/4/2019 Introductory Course on C++

    30/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 30/209

    Integer Types

    Integer types: int: the basic integer type of the size of one machine word (most

    efficient) short int (or short for short): integer of size less than or equal

    to the size ofint

    long int (or long for short): integer of size greater than orequal to the size ofint

    Variants of the same size as the primary type: signed (default): values may be negative

    unsigned: values are always non-negative

    Conversions to smaller-sized types or from signed tounsigned and vice versa may lose information (warning,not compilation error)

    Examples:short si = 127; // signed short intunsigned long

    ul = 123456UL; // unsigned long int

  • 8/4/2019 Introductory Course on C++

    31/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 31/209

    Floating-Point Types

    Types for floating-point rational numbers: double: default floating-point type

    float: floating-point of size less than or equal to thesize ofdouble

    long double: floating-point of size greater than orequal to the size ofdouble

    Conversions to smaller-sized types may loseinformation or precision (warning, not compilationerror)

    Examples:float pi = 3.14;double d = 1.5e-4;long double dl = 1.3;

  • 8/4/2019 Introductory Course on C++

    32/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 32/209

    Enumerations

    Enumeration is a type that defines a finite set of discretesymbolic values. Its instances may take only the valuesfrom the set

    Examples:enumBool { false, true };enumReply { YES, NO, CANCEL };

    enumStatus { initiated, suspended,committed, canceled, failed };

    Status s1 = initiated;...

    if (s1==committed) ...

  • 8/4/2019 Introductory Course on C++

    33/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 33/209

    Enumerations

    There is a standard (built-in) conversion from anenumeration value to an int, resulting in the value of the

    order number of the symbol in the set, starting from 0:enumStatus { initiated, suspended,

    committed, canceled, failed };

    int i = suspended; // i gets the value 1Status s = canceled;...if (s==4) ... // conversion Status->int;

    // evaluates to true if s==failed

    The default ordering can be changed:enumStatus{ initiated = 1, suspended, //suspended = 2committed, canceled = 5,failed = committed+4 }; // failed = 7

    The opposite conversion (intpenum) may not be implicit:Status s = 3; // Error!

  • 8/4/2019 Introductory Course on C++

    34/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 34/209

    Enumerations

    Enumerations should be used whenever there is a need fora data type that abstracts a concept from the problemdomain and its instances take values from a finite discreteset of symbolic values

    It is not wise to use a built-in integer type instead of anenumeration in that case, because: the program is more difficult to understand, because the abstract

    type is mixed with the built-in integer type

    the values of the abstract type should not take part in arithmetic

    operations (addition, subtraction, multiplication, etc.) the program is less flexible: if there is a need to change the

    decision about the implementation of the abstract type, it is difficultto find those occurrences of the type that are not really theintentional usage of built-in integer types and replace them

  • 8/4/2019 Introductory Course on C++

    35/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 35/209

    Pointers

    A pointer is an object that points to another object

    In C++, pointers are implemented as memory cells that

    carry values of the addresses of pointed objects inmemory; however, this is a matter of implementation andthe concrete value of a pointer should not be considered,except in special cases of debugging pointers

    A pointer realizes a unidirectional link to an object; there is

    no additional information about the linkage of the pointerand the pointed object and no runtime checking of pointervalidity; consequently, pointers are not safe against somesevere problems, and the programmer is responsible for

    the pointers validity

    anObjectaPointer

  • 8/4/2019 Introductory Course on C++

    36/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 36/209

    Pointers

    If a pointer p points to an objectx, then theoperation *p results in the objectx (pointer

    dereferencing)The operation &x results in a pointer value thatpoints to the objectx (address operation)

    Pointers are derived types: there is no a pointer

    (just like this), but a pointer to T. The typepointer to T is denoted with T*:T x;T* p = &x; // &x is of type T*...*p... // *p is of type T and refers to x

    T xT* p

  • 8/4/2019 Introductory Course on C++

    37/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 37/209

    2int* pi

    0

    i

    int

    0

    j

    1Pointers

    int i=0, j=0;int* pi = &i;

    *pi=2;

    j=*pi;

    pi=&j;

    2

    3

    24

    int* pi

    5

    Counter* p = new Counter(4);

    p->inc(); // call inc() of *P

    (*p).inc(); // the same

  • 8/4/2019 Introductory Course on C++

    38/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 38/209

    2

    int* pi 0

    i

    int

    0

    j

    1

    Pointers

    Pointers are objects that point to objects, including otherpointers:int i=0, j=0;int* pi=&i;int** ppi; // pointer to- pointer to - int";ppi=

    *pi=1;**ppi=2; // Evaluated: *(*ppi)*ppi=&j;ppi=&i; // Compilation error:

    // int* cannot be converted to int**

    1

    54

    int** ppi

    3

    2

    6

    7

  • 8/4/2019 Introductory Course on C++

    39/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 39/209

    Pointers

    A pointer of type void can point to an object of any type(typeless pointer). There are no objects of type void, onlypointers of type void*. void* pointers are not used inOO programs because they are not type-safe; they areused in low-level programming when accessing raw data in

    computer memory or hardware registersCounter* c = new Counter(7);void* p = c;

    p->inc(); // Compilation error: *p is not a Counter!

    A pointer can point to nothing a null pointer with the

    symbolic value 0. The value 0 is a symbolic value, notnecessarily the binary value of the pointersimplementation (although often so). A pointer can be: initialized or assigned the null value: int* p=0; ... p=0;

    checked against the null value: if(p==0)... if(p!=0)...

  • 8/4/2019 Introductory Course on C++

    40/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 40/209

    Pointers

    C/C++ pointers are very unsafe and may cause severebugs. Here are some most often problems

    Invalid pointer Cause: dereferencing a pointer with an invalid value (points to an

    invalid object, its value is an invalid or corrupted address); neither

    a pointer nor its pointed object are checked against validity atruntime:Counter* p; // Pointer has undefined default value

    p->inc(); // Possible runtime error!

    Effect: a possible (but not always) runtime error or exception (memory access

    violation or program blockage) a bug (invalid result of an operation)

    Typical cases of occurrences: uninitialized pointer:Counter* p; // No default initial value!p->inc(); // Possible runtime error or exception!

  • 8/4/2019 Introductory Course on C++

    41/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 41/209

    Pointers

    corrupted pointer:int a[5]; // array of 5 integers in range [0..4]

    Counter* p = new Counter(2);

    // p is probably allocated behind the array

    for (int i = 0; iinc(); // p is probably corrupted!

    Cure: careful programming

    always initialize pointers

    check indices against array boundaries compilers sometimes warn you to these problems

  • 8/4/2019 Introductory Course on C++

    42/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 42/209

    Pointers

    Null-pointer dereferencing Cause: dereferencing a pointer with a null value; a pointer is not

    checked against null value at runtime:Counter* p = 0;

    p->inc(); // Runtime error (probably hardware exception)!

    Effect: a runtime error on almost all platforms (a memory-access-violation

    hardware exception in most cases)

    Typical cases of occurrences: non-checked pointer value, typically as a result of a function:Counter* getCounter(...); // function that returns a ptr...

    Counter* p = getCounter(...); // May return 0p->inc(); // Possible runtime error!

    non-checked result ofnew; when there is no free memory, newreturns null:Counter* p = new Counter(7); // May return 0p->inc(); // Possible runtime error!

  • 8/4/2019 Introductory Course on C++

    43/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 43/209

    Pointers

    Cure: always check the pointer as a result of a function or new:

    Counter* p = getCounter(...); // Or:

    Counter* p = new Counter(7);

    if (p!=0) p->inc();

    never believe in pointersalways check them beforedereferencing (very conservative) :if (p!=0) ...p->...

    if (p!=0) ...*p...

  • 8/4/2019 Introductory Course on C++

    44/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 44/209

    Pointers

    Dangling pointer: Cause: dereferencing a pointer that points to a destroyed object;

    the pointer is not notified on destruction of the pointed object:Counter* p = new Counter(5);delete p;p->inc(); // Bug: *p does not exist any more!

    Effect: a bug due to the access of invalid objects sometimes a runtime error, blockage, or exception, because the

    memory space of the destroyed object may have been allocated byother system data

    Typical cases of occurrences:

    invalid use of objects and pointers:Counter* p = new Counter(3);... // In another context:Counter* q = p;... // In yet another context:

    delete p; // p and q dont change their values even to 0... // In yet another context:...*q... or ...q->...

  • 8/4/2019 Introductory Course on C++

    45/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 45/209

    Pointers

    returning pointers to automatic (local) objects placed on thestack from functions:int* f() {

    int x = 5; // a local, automatic integer...

    return &x; // x dies on function return

    }...

    int* p = f(); // p is a dangling pointer!

    Cure: Careful programming

    Compilers often warn you to dangling pointers, especially asreturn values of functions

  • 8/4/2019 Introductory Course on C++

    46/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 46/209

    Arrays

    An array is an object that represents an ordered,bounded collection of objects with a fixed sizedetermined at the time of its creation

    Arrays are derived types: there is no an array(just like this), but an array of objects of type T.The type an array ofTs is denoted with T[]:int a[100]; // An array of 100 ints

    The indices of an array are always in the range[0..n-1]:a[2] = 5; // access to the third elementa[50] = a[0]+a[99];

    T T T ... T T0 1 2 ... n-2 n-1

  • 8/4/2019 Introductory Course on C++

    47/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 47/209

    Arrays

    There is no runtime range-checking of indices. Therefore,runtime errors are possible due to range errors (corruptionof other data or runtime exceptions due to memory accessviolations)

    An element of an array may be any object, even anotherarray (multidimensional arrays):int m[5][7]; // a 5 x 7 matrixm[3][5] = 2; // evaluated as (m[3])[5];

    // m[3] is the 4th element of m;// it is an array of 7 ints;

    // (m[3])[5] is its 6th integer element

  • 8/4/2019 Introductory Course on C++

    48/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 48/209

    Arrays

    Due to its orientation to efficiency, C/C++ arrays are usedin operations with as little information about them aspossible; to generate the code to access an element of anarray, apart from the index, the compiler needs: the starting address of the array

    the size of an element, which is determined by its typeThis information can be deduced from a pointer to the firstelement of the array.

    For example, arrays are not passed to functions by value(as entire packages of elements), but by a pointer to their

    beginning. Consequently, the invoked function does nothave an implicit information about the array size theymust be provided by the program semantics!

    Therefore, arrays and pointers are tightly coupled by thefollowing rules

  • 8/4/2019 Introductory Course on C++

    49/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 49/209

    Arrays

    Rule #1: Whenever an array (of type T[]) is used in anoperation (except for &), it is implicitly converted into apointer (of type T*) that points to the arrays first element:T[] p T*

    Rule #2: For a pointer (of type T*) and an integer, the

    operations of additions and subtractions are defined; if apointer p points to an element of an array, the result ofaddition p+i (where i is an integer) is a value of a pointerthat points to the element of the same array, i places

    ahead: T T T ... T T

    p p+i

    i

  • 8/4/2019 Introductory Course on C++

    50/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 50/209

    Arrays

    Rule #2 (continued): The result is defined provided that the pointer points to an element of an array and

    the resulting pointer points to an element of the same array, or oneelement behind (not allowed to dereference)

    These rules are not checked at runtime: the compiler does

    not generate the code for checking against these rules, butsimply the code that sums up the value of the pointer andthe value of the integer multiplied by the size of an element.If the rules are not satisfied, there is no compilation warningor error, but the result will be undefined (a silent bug due to

    invalid or corrupted data or a runtime exception due tomemory access violation).

    The similar holds for subtraction of an integer from a pointer(the result is a pointer i places backward) or for subtractionof two pointers that point to elements of the same array (the

    result is an integer).

  • 8/4/2019 Introductory Course on C++

    51/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 51/209

    Arrays

    Rule #3: The expression a[i] is treated as *(a+i) bydefinition

    Consequences: the treatment of array indexing operation:

    int a[10];

    int* p = &a; // p points to a[0];a[2]=1;p[3]=3;

    p=p+1;*(p+2)=1;

    p[-1]=0;

    The same as: = a; because a is converted into &a

    a[2]|*(a+2) by Rule #3 in *(a+2), a is converted into a pointer to its first element

    of type int* by Rule #1 the pointer is added with 2 by Rule #2, and the result of(a+2) is a pointer that points to a[2] the resulting pointer is dereferenced by *(a+2), and theresult refers to the pointed object that is exactly a[2]

    p[3]|*(p+3) by Rule #3 the pointer is added with 3 by Rule #2, and the result of(p+3) is a pointer that points to a[3] the resulting pointer is dereferenced by *(p+3), and theresult refers to the pointed object that is exactly a[3]

    By Rule #2, a pointer is added with 1 and the resultpoints to the next element in the array

    The same as p[2]

    The same as *(p-1). The result of p-1 is a pointerthat points one element in front of the one pointedto by p

  • 8/4/2019 Introductory Course on C++

    52/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 52/209

    Arrays

    arrays cannot be passed to functions by value (as entirepackages of elements), but only pointers to their firstelements are passed (by value):voidsort (int* p); // A fn that accepts an int*

    voidqsort (int a[]); // Also accepts an int*,

    // because it can be called by:int a[10];qsort(a); // a is converted into int*

    consequently, T[] and T* as types of arguments aretreated uniformly

    when arrays are passed as arguments, the argumentsdo not carry the information about the size of the array(C/C++ arrays do not carry this information); this mustbe ensured by the program semantics; for example:int sumUp (int a[], int numOfElements);

  • 8/4/2019 Introductory Course on C++

    53/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 53/209

    Arrays

    for that purpose, the compiler terminates string-literals with \0 bydefault:char s[] = Hello;

    char* p = World;

    char q[5] = {H,e,l,l,o};

    s is an array of 6 characters

    p is a pointer (not an array) toan array of 6 chars

    for the same purpose (implicit information about array size), thereis a traditional C convention for the arrays of characters: theyshould be always terminated by \0 (null-terminated strings); alllibrarian functions that deal with strings expect such arrays; if an

    array is not terminated so, the function will not work correctly (itmay loop until it accidentally comes across a null byte in memory):int strlen (char* p);

    // Expects a null-terminated string

    // Returns the size of the string,

    // without counting in \0q is an array of 5 chars, initialized to the given

    values, but it is not null-terminated!

    H e l l o w o r l d \0

  • 8/4/2019 Introductory Course on C++

    54/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 54

    Chapter 6: Declarations and Scopes

    Declarations

    ScopesGlobal Scope

    Local Scope

    Class Scope

  • 8/4/2019 Introductory Course on C++

    55/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 55/209

    Declarations

    A declaration introduces a name (identifier) into aprogram:int a = 3; // an object of type int

    int* p = &a; // an object of type int*

    voidf(int); // a function that

    // accepts an int and returns no resultint* g(char*,int); // a function that// accepts a char* and an int and returns an int*

    class Counter; // a class named Counter

    Counter* pc; // an object of type Counter*

    Any name in the program must be declared before it isused

    A declaration lets the compiler know about the languagecategory of the name (a type, an object, a reference, afunction, etc.) and its type

  • 8/4/2019 Introductory Course on C++

    56/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 56/209

    Declarations

    After processing a declaration, the compiler: adds the name into its symbol table, along with the information

    about the names language category and type

    possibly allocates the space for an object, generates the code forits initialization, or generates the code for a function body

    checks the usage of the name afterwards according to its categoryand type information from the symbol table, and reports violations(compilation errors)

    knows how to compile the code when the name is used afterwards

    A definition is a declaration that: (declaration of an object) initializes (creates) an object or

    (declaration of a function) defines the body of a function or

    (declaration of a class) declares the members of a class

  • 8/4/2019 Introductory Course on C++

    57/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 57/209

    Declarations

    Declarations of objects: which are not definitions (do not initialize objects):extern int a, b;extern Counter* theCounter;

    After such a declaration, an object can be used freely (all

    operations are allowed), provided it is definedsomewhere in the program

    which are definitions (do initialize objects):int a, b=0; // a has an undefined initial valueCounter *p, *q = new Counter;// p and q are of type Counter*;// p has an undefined initial value

    Objects of built-in types do not have default initial value;unless they are explicitly initialized with an initializer,they will have an undefined value (whatever isencountered in memory)

  • 8/4/2019 Introductory Course on C++

    58/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 58/209

    Declarations

    Declarations of functions: which are not definitions (do not define bodies):int f(), sqr(int); // f has no arguments,// sqr accepts an int, both return an int

    voidCounter::inc(); // a member of Counter

    After such a declaration, the function can be used freely(it can be invoked), provided it is defined somewhere inthe program.

    The name of formal arguments are not relevant in these

    declarations (the compiler ignores them). They shouldbe provided in order to increase the readability.

    which are definitions (do provide bodies):voidCounter::inc() { counter=counter+1; }

    int sqr(int i) { return i*i; }

  • 8/4/2019 Introductory Course on C++

    59/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 59/209

    Declarations

    Declarations of classes: which are not definitions (do not declare members):class Counter;

    After such a declaration, only pointers and references toobjects of that class can be defined, but no other

    operations on these objects are possible; used to reducecompilation dependencies among program modules:class Counter;class Clock {

    public:Clock(Counter*); // Decl. of a constructor

    private:Counter* myCounter;

    };

    which are definitions (declare all members); objects canbe defined and manipulated after such definitions

  • 8/4/2019 Introductory Course on C++

    60/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 60/209

    Scopes

    Scope is a part of the program source code inwhich a declared name can be used (it is said tobe in scope)

    Scope is a notion exclusively bound to: the space dimension (relates with a part of the program

    source code)

    compilation time (scopes are resolved at compilationtime only and have no effects at runtime)

    A name can be used in its scope directly. Outsideits scope, the name can be accessed in a specificway or not used at all

  • 8/4/2019 Introductory Course on C++

    61/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 61/209

    Scopes

    Scopes can be nested: if a name is declared in a nestedscope, it hides the same name declared in an enclosingscope, meaning the following: when a name is used, the compiler tries to bind it to the

    declaration that describes that name

    it first tries to find the declaration in the inner-most nested scope(the current scope)

    if the declaration is not found there, the compiler searches the firstenclosing scope, etc. outward, until a declaration is found

    if no declaration is found, the compiler reports an error (name not

    declared)The language defines the rules of scope nesting

  • 8/4/2019 Introductory Course on C++

    62/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 62/209

    Scopes

    Example:int x = 0;

    voidf () {

    int x = 1;

    x = 3;

    }

    class Dummy {public:

    int x;

    };

    A global x of file scope

    Scopes in C++: global (file)

    local (block)

    class

    function (not covered by this course)

    Start of a nested scope

    Hides the global xRefers to the x from the nested

    scopeEnd of the nested scope; thelocal x is no more in scopeStart of a nested scope

    Hides the global x

    End of the nested scope; the member x is no morein scope

  • 8/4/2019 Introductory Course on C++

    63/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 63/209

    Global Scope

    A name has the global scope if it is declared outside allclasses and function bodies

    A global name is in scope from the place of its declarationto the end of the compilation unit (the source code file)

    A global name can be accessed from a nested scope,although it is hidden, over the :: operator:int x = 0; // global x, in scope to the end of file

    voidf () { // a nested scope

    int x = 2; // hides the global x

    x = 3; // access to x from the nested scope::x = 3; // access to the global x

    } // end of the nested scope

    int* p = &x; // access to the global x

  • 8/4/2019 Introductory Course on C++

    64/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 64/209

    Local Scope

    A name has a local scope if it is declared inside acompound statement (a block between braces {}),including a function body

    A local name is in scope from the place of its declaration tothe end of the block in which it is declared

    A block is a nested scope for an enclosing block or the file(the global scope):int x;

    voidf () {int x = 1;

    x = 2;{int x = 0;x = 2;

    }x = 3;

    }

    A global x of file scope

    Start of a nested compound statement(block) and scope

    A local x, hides the global x

    Refers to the local x

    A nested local x, hides the globaland the enclosing local onesRefers to the second local xEnd of the nested scopeRefers to the first local x

  • 8/4/2019 Introductory Course on C++

    65/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 65/209

    Local Scope

    The same declaration of a name can be repeated in thesame scope, unless it is a definition

    Formal arguments of functions have a local scope of theoutermost block of the function body:voidf(int x) { // argument x has a local scope

    int x = 0; // Compilation error:// multiple definitions of the same name

    ...

    }

  • 8/4/2019 Introductory Course on C++

    66/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 66/209

    Class Scope

    A name has a class scope if it is declared inside a classdefinition; all names declared inside a class definition arecalled its members: data members and member functions

    types: typedefs, enumerations, structures, unions, classes

    class DatabaseManager {public:

    enumDBStatus { ok, failed, refused };DatabaseManager (char* name); // ConstructorDBStatus openConnection();DBStatus closeConnection();

    DBStatus getConnectionStatus();DBStatus performQeury (char* sqlQuery);

    private:char* name;...

    };

  • 8/4/2019 Introductory Course on C++

    67/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 67/209

    Class Scope

    A name with a scope of class X can be accessed: directly, within the same scope:DatabaseManager::DatabaseManager(char* nm) {name = new char[...]; // name is in scope

    ...

    } over an object of type X and . operator:voidmain (){

    DatabaseManager* p = new DatabaseManager(...);...

    (*p).openConnection();...

    }

    over a pointer of type X* and -> operator:p->openConnection();

  • 8/4/2019 Introductory Course on C++

    68/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 68/209

    Class Scope

    over the :: operator (X

    ::memberName):class Base {

    public:virtual voidf(); // polymorphic function

    };

    class Derived :public Base {public:

    virtual voidf(); // redefined operation};

    voidDerived::f () {...f();Base::f();...

    }

    End of scope of class Derived; the only active

    scope is global

    f() is from the scope of class Derived Reactivation of that class scope

    Start of a nested local scope

    We want to call the Base class version off(). This is an error, because f is searchedfor:

    in the active local scope (not found) in the active class scope Derived (found)Thus, this is an endless recursion!

    Correct: start the search from the Base classscope (and possibly the scopes of its baseclasses)

  • 8/4/2019 Introductory Course on C++

    69/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 69/209

    Class Scope

    Types can be defined in a class scope, e.g., classes orenumerations. If a class is defined inside another class,this is only the matter of scopes and there is no othermeaning (no object embodying, no special access rightsamong the classes):class List {

    public:enumStatus { ok, error };

    List ();Status put (Object* anItem);...

    private:class ListElement { // nested classListElement (ListElement*); // constructor//...

    };};

  • 8/4/2019 Introductory Course on C++

    70/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 70/209

    Class Scope

    List::Status List::put (Object* p) {...

    return ok;

    }

    List::ListElement::ListElement

    (List::ListElement* next) {...}

    Status is not in scope. It must be accessedthrough the operator ::

    ok is now in scope, because the List class scopeis active ListElement is not in scope. It

    must be accessed this way.

    A nested type is used when it is needed only for animplementation of another class. Nested types aregenerally equivalent to global types, except that:

    they do not pollute the global name space, thus reducing chancesfor name clashing

    they are logically packed into a proper class, thus improvingreadability and understandability of the program

    access to them may be controlled (they can be public, protected, orprivate), allowing their encapsulation

  • 8/4/2019 Introductory Course on C++

    71/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 71

    Chapter 7: Object Lifetimes

    Object Lifetime

    Automatic ObjectsStatic Objects

    Dynamic Objects

    Data MembersTemporary Objects

    Object Initialization and Destruction

  • 8/4/2019 Introductory Course on C++

    72/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 72/209

    Object Lifetime

    An object lifetime is the time interval from its creation tillits destruction. The object can be accessed only during itslifetime

    In the beginning of its lifetime, an object is initialized. If itis an object of a class, its constructor is called.In the end of its lifetime, the object is destroyed. If it is anobject of a class, its destructor is called.There is no exception to this rule, regardless of the lifetimecategory

    Lifetime is a concept orthogonal to scope: it is time-related (instead of space-related)

    it is runtime-related (instead of compilation-related)

  • 8/4/2019 Introductory Course on C++

    73/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 73/209

    Object Lifetime

    Categories of lifetimes in C++ automatic

    static

    dynamic

    data members

    temporary objects

    One of the main design principles of C++ is that objects ofall types (built-in as well as user-defined) can be of alllifetime categories

  • 8/4/2019 Introductory Course on C++

    74/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 74/209

    Automatic Objects

    An automatic object lives from the time of execution of itsdefinition, until the execution exits its scope (block)

    Automatic objects are local objects not specified asstatic

    Every time the flow of control executes a definition of anautomatic object, a new incarnation of that object iscreated; this allows nested and recursive function calls:int f (...) {int i = ...;

    ... f(...)...for (i=0; i

  • 8/4/2019 Introductory Course on C++

    75/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 75/209

    Automatic Objects

    Automatic objects are placed on the program control stack:when a function is called, an activation block of itsautomatic objects is created on the stack; when it isfinished, the activation block is cleared from the stack; thecompiler compiles operations with automatic objects byaddressing modes relative to the top of the stack

    Formal arguments of functions are automatic by theirlifetime. When a function is called, the formal argument iscreated as an automatic object and initialized by the actualargument. The initialization semantics are the same as for

    any other initialization:voidf (X x1) {...}

    voidg () {...f(x2)...

    }

    At the time of function invocation

    f(x2), local automatic x1 is createdand initialized by x2; the semanticsare the same as in the definition:X x1=x2;

  • 8/4/2019 Introductory Course on C++

    76/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 76/209

    Automatic Objects

    Objects of classes can be automatic, too. Constructors anddestructors are invoked at the beginning and end of theirlives:voidmain () {

    Counter c1(3), c2(3); // automatic objects

    c1.inc(); // call inc() of c1...} // destructors of c1 and c2 are called here

    Substitution does not take place for these objects, becausethey are always exactly the objects of the specified class

    known to the compiler, identified directly by their names:Derived d; // an object of a derived classBase b = d; // b is certainly a Base, nothing else!

  • 8/4/2019 Introductory Course on C++

    77/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 77/209

    Automatic Objects

    An automatic object is created when the executionencounters its definition. Consequently, an automaticobject does not need to be created at all; if it is not, it willnot be destroyed, either (constructor and destructor willnot be called):voidmain () {...

    if (...) {

    Counter c1(2); // c1 may never be created...

    } // destructor for c1 is called here

    }

  • 8/4/2019 Introductory Course on C++

    78/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 78/209

    Static Objects

    A static object lives from the moment of execution of itsdefinition, till the end of the program. There is only oneincarnation of each static object during the execution ofthe program

    Static objects are: all global objects

    local objects declared as staticCounter c(2); // global static objectvoidf () {

    static Counter c(3); // local static object

    }

  • 8/4/2019 Introductory Course on C++

    79/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 79/209

    Static Objects

    The moment of creation of a static object depends on itsscope: global static objects are created at a moment on program startup,

    not necessarily before the invocation ofmain(); the moment of

    their initialization is not guaranteed; recommendation: avoid global

    static objects of classes local static objects are created when the flow of control comes to

    their definition for the first time; they are initialized only when thedefinition is encountered for the first time, every other time thedefinition is skipped;

    Static objects are stored in a static memory space,allocated at compile time. Static objects of built-in typesmay often be initialized at compile time:static int a = 5; // may be initialized

    // at compile time

  • 8/4/2019 Introductory Course on C++

    80/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 80/209

    Static Objects

    Local static objects are secure with initialization.Recommendation: instead of global static objects ofclasses, use local static objects of classes. If a definition ofa local static object is never executed, the object will notbe created nor destroyed (the constructors and destructors

    will not be called):Counter* Counter::Instance() {

    static Counter instance(0);

    return &instance;}

    Here, the local static object is created (its constructor iscalled) when the function Instance() is first called, if

    ever

  • 8/4/2019 Introductory Course on C++

    81/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 81/209

    Static Objects

    Local static objects survive over subsequent invocations oftheir enclosing functions:int a=1;

    voidf () {int b=1; // initialized at each call

    static int c=1; // initialized only oncecout

  • 8/4/2019 Introductory Course on C++

    82/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 82/209

    Dynamic Objects

    The lifetime of a dynamic object is explicitly controlled bythe program semantics. A dynamic object is explicitlycreated by the operator new, and is explicitly destroyed bythe operator delete:Counter* p = new Counter(3);...

    delete p;

    Dynamic objects survive the execution of functions and arenot tied to implicit destruction, as automatic and staticobjects:Counter* pc = 0;

    voidf() {pc = new Counter(2);}voidmain () {f();delete pc;

    }

  • 8/4/2019 Introductory Course on C++

    83/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 83/209

    Dynamic Objects

    The operator new:new T(init)

    allocates a space in memory to store an object of typeT; by default, the space is allocated in a special memory

    section assigned to a program, managed by a built-inmemory manager, called the freestore or the heap;however, this behavior can be changed for a class

    initializes the object by simple copying the result of the initializer expression init to

    the allocated space, ifT is a built-in type calling the constructor ofT that accepts the initializer init to

    initialize the object, ifT is a class

    returns the pointer to the created object of type T*

  • 8/4/2019 Introductory Course on C++

    84/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 84/209

    Dynamic Objects

    The created dynamic object is always anonymous. The solelink to it is the pointer returned by new. If that pointer islost, there is no way to access the anonymous dynamicobject, even to delete it:int* p1 = new int(3); // correctint p2 = new int(3); // compilation error:

    // incompatible typesint p3 = *new int(3);// no compilation error,

    // but the object is lost!

    The operator delete:delete ptr

    if the result of the expression ptr is a pointer to a class, calls thedestructor for the object pointed to by ptr

    releases the space allocated for the object; by default, it is done bya built-in heap manager, but it can be changed for a class; ptrmust point to an object created with new, otherwise a runtimeerror may occur

  • 8/4/2019 Introductory Course on C++

    85/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 85/209

    Dynamic Objects

    Allocation of a dynamic array:char* str2 = new char[strlen(s1)+1];T* a = new T[n][5];

    When an array is allocated: all but the first dimensions must be evaluated at compile time; the

    first dimension may be computed at runtime (this is the reason for

    creating dynamic arrays) no initializers can be specified:

    if the type of the elements is a built-in type, the elements haveundefined initial values; the values must be set in a separate loop

    if the type of the elements is a class, it must have a constructor thatmay be called without arguments, which is then called for each

    element in order of indices; otherwise, a compilation error occurs new returns a pointer to its first element

    A dynamic array must be deleted this way:delete [] str;delete [] a;

  • 8/4/2019 Introductory Course on C++

    86/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 86/209

    Dynamic Objects

    A potential problem with dynamic objects:Memory Leakage Cause: dynamic objects are repetitively created, but not

    destroyed (forgotten deletes)

    Effect: after a long run, the freestore is exhausted new then returns 0, possibly causing the null pointer

    dereferencing problem, or the program simply does not work asintended

    Typical cases of occurrences:A function creates a dynamic object, but it is forgotten to be

    destroyed in the clients context:X* getAnX(); // It is not obvious who is responsible

    // to destroy the returned objectX* pX = getAnX();// there is no delete pX afterwards

  • 8/4/2019 Introductory Course on C++

    87/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 87/209

    Dynamic Objects

    Cure:Use a naming convention for functions that return

    objects for which the client code is responsible todelete:X* getAnX(); // client not responsible to delete

    X* createX(); // client responsible to deleteX* pX1 = getAnX();X* pX2 = createX();...delete pX2;

    Some tools that monitor execution of a system may

    help you to find memory leakage

  • 8/4/2019 Introductory Course on C++

    88/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 88/209

    Data Members

    The lifetime of a data member object is bound to thelifetime of the enclosing object: it is created when the enclosing object is being constructed

    it is destroyed when the enclosing object is being destroyed

    class Clock {public:

    Clock(); // Constructor~Clock(); // Destructor

    private:Counter c; // Data member object of class Counter

    };

    Clock::Clock() : c(0) { ... }

    Clock::~Clock() {...

    }

    The constructor of the datamember c is called here

    The destructor of the datamember c is called here

  • 8/4/2019 Introductory Course on C++

    89/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 89/209

    Data Members

    A data member is initialized in the list of initializers of aclass constructor, behind :. Every other operation on the

    data member in the body of the constructor is an operationon an already initialized member:class Counter () {

    public:Counter (int i);

    private:

    int counter;

    };

    Counter::Counter (int i) : counter(i) {counter = ...

    }

    Thisis the initialization of thedata member counter

    This is not an initialization, butan operation: counter hasbeen already initialized

  • 8/4/2019 Introductory Course on C++

    90/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 90/209

    Data Members

    Each data member is initialized in the list of initializers,either explicitly or implicitly, before the body of theconstructor is executed. If an explicit intializer for a datamember does not exist in the list, the initialization isimplicit: for objects of built-in types, the initial value is undefined

    objects of classes are initialized by calling the constructor that maybe called without actual arguments; if such a constructor does notexist in the class, there is a compilation errorClock::Clock() {...

    }

    Error: counter data member cannot beinitialized implicitly, because the classCounter does not have a defaultconstructor!

    Similar holds for destructors, except that: a class always has a destructor

    built-in types do not have destruction

    destructors of data members are called after the completion of thebody of the enclosed objects destructor

  • 8/4/2019 Introductory Course on C++

    91/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 91/209

    Temporary Objects

    The lifetime of a temporary object is short and under thecontrol of the compiler: a temporary object is created as a result of an operation, including

    a function call

    a temporary object is destroyed when it is not needed any more

    (as an operand of another operation), sooner or later (the matterof the compiler)

    Temporary objects are those created as results ofoperations, including results of function calls. They arealways anonymous:double f(double), log(double);int n = i + j k;

    double d = f(u)+log(x);int m = aCounter.val()+5;

    The result of (i+j) is a temporary, anonymous int

    The result of (?-k) is a temporary, anonymous int

    The result of f(u) is a temporary, anonymousdouble

    The result of log(x) is a temporary, anonymoudouble

    The result of call aCounter.val() is a temporaryanonymous int

  • 8/4/2019 Introductory Course on C++

    92/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 92/209

    Temporary ObjectsRegardless to the exact moment of their creation anddestruction, temporary objects are initialized anddestructed as all other objects: for objects of classes,constructors and destructors are called consistently

    A result of a function call is a temporary, anonymous

    object, created in the context of function invocation (in thecontext of an expression where the function call is), at themoment when the function returns a value. The temporaryobject is initialized with the result of the expression in thereturn statement. The semantics of this initialization arethe same as for any other initialization:X f () {return x1;

    }

    ...f()... // an expression with a function call

    The result of f() is a temporary, anonymous X, initializedat the moment of function return, as in: X temp(x1)

  • 8/4/2019 Introductory Course on C++

    93/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 93/209

    Object Initialization and Destruction

    In declarations, an object can be initialized using thenotation X x1 = x2, provided that the object is either of

    a built-in primitive type, or of a class that has a constructorthat can be called with one actual argument. Except for asubtle difference, this is equal to the notation X x1(x2)

    At all other places, an object is initialized using thenotation X x1(list_of_initializers)optional

    An implicit initialization (without explicit initializers) ispossible for:

    built-in types; the initial value is undefined objects of classes that have constructors that can be called with no

    actual arguments

  • 8/4/2019 Introductory Course on C++

    94/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 94/209

    Objects Initialization and DestructionThe order of objects creation is defined in almost all cases: for global static objects, the order is undefined except for the

    objects in the same file

    for local static, automatic, and dynamic objects, the order isdefined by the order of execution of their definitions or newoperators

    for data member objects, the order of creation is defined by theirorder of declarations in the class, regardless to the list of theirinitializations in the class constructors

    for temporary objects, the order is defined by the order ofevaluation of operations

    elements of an array are created in the increasing order of theirindices; the initialization of elements is always implicit

    Objects are destroyed (destructors are called for objects ofclasses): only if they have been constructed

    always in exactly the reverse order of their creation

  • 8/4/2019 Introductory Course on C++

    95/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 95

    Chapter 8: Program Structure

    Structure of Units

    CompilationLinking

    Preprocessor

  • 8/4/2019 Introductory Course on C++

    96/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 96/209

    Structure of UnitsIn C and C++, a program consists of a number of units(modules), whereby a unit is one file with source code(usual extensions are .c and .cpp)

    One file is a separate compilation unit: the compiler doesnot cross the boundaries of a singe file. A file is the only

    scope of compilationAccording to the the general rule, a name can be used onlyif it is previously declared. Therefore, a file must have thedeclarations for all names used in it

    A source file consists of declarations only (some of them

    being definitions): global objects

    classes and other types

    functions

  • 8/4/2019 Introductory Course on C++

    97/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 97/209

    B.objA.obj

    int a = 3;

    void f() {

    ...}

    void g() {...f()...

    ...a...}

    A.cpp B.cpp

    Compilation

    a: 3

    f: ......

    ...

    oa: 0

    of: 1...

    a and f must bedeclared beforeusage

    int a;

    void f();

    This is a definition

    which will causespace allocation

    a: ?

    ...

    extern int a;

    void f();

    This isnt a definition

    og: 0

    qf: ...

    qa: ...

    g:

    ...?f...

    ...?a...

    ...

  • 8/4/2019 Introductory Course on C++

    98/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 98/209

    Linking

    The linker has a task to collect a set of .obj files (A.obj,B.obj, C.obj, etc.) and to make an executable program(P.exe)

    The linker makes it in two passes: makes a global map of .obj files and a symbol table of exported

    symbols and their computed global addresses

    resolves the references to imported symbols using the computedaddresses from the symbol table

    B.objA.obj a: 3f: ...

    ...

    ...

    oa: 0

    of: 1...

    og: 0

    qf: ...

    qa: ...

    g:

    ...?f...

    ...?a...

    ...

    A.obj

    B.obj

    C.obj

    ...

    P.exe

  • 8/4/2019 Introductory Course on C++

    99/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 99/209

    LinkingLibraries have the same form and meaning as ordinary .objfiles, except that they are prepared by compiling andlinking a set of source files (.lib files)

    The linker treats libraries in the same way as other .objfiles

    Some libraries are provided with the compiler environment(e.g., standard libraries)

    Possible linker errors: a symbol not defined; the linker reports only the name of the .obj

    file which imports the unresolved symbol; often very confusing,

    because your code might not use the symbol at all; possible cause:the symbol is used in an included library, but the library whichdefines the symbol is not included in the linkers list

    multiple definitions of a symbol; the linker reports the names of the.obj files that define the symbol; possible cause: multipledefinitions in several .cpp files

  • 8/4/2019 Introductory Course on C++

    100/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 100/209

    Preprocessor

    Consequence: for each program element N that is definedin a file A and should be used in many other files B,declarations must exist in all these files B

    Problem: how to keep the declarations consistent in caseof modifications? Example:

    A.cpp double a = 3; B.cppextern int a;

    void g() {

    ... = a+3...}

    The type of a has beenchanged into double

    The extern declarationforgotten to be updated

    The compiler will generatethe code that operates withan int, which is totallydifferent from the code thatdeals with a double

    This error cannot be detected either by the compiler, because it does not consider cross-file

    declarations (a file is an independent compilation unit)

    or by the linker, because it does not have any idea about the typesof the symbols; the linker deals solely with mapping of (typeless)symbols to their addresses

  • 8/4/2019 Introductory Course on C++

    101/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 101/209

    PreprocessorThe preprocessor is a program that transforms the sourcecode of a file before its compilation. It is a part of theC/C++ compiler (in a broader sense)

    Thus, the compilation (in a broader sense) is performed intwo phases (or pipes): preprocessing and compilation

    The preprocessor works exclusively with the source codeas a text, and transforms it into the output text that ispassed to the compiler. The preprocessor does notconsider any language-related issues, so it does notrecognize program elements

    The preprocessor is controlled by the preprocessordirectives that specify the transformations of the textPreprocessor directives start with # and last till the end ofline, except when the line ends with \, when the directiveis continued in the next line

  • 8/4/2019 Introductory Course on C++

    102/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 102/209

    Preprocessor

    There are several preprocessor directives in C/C++. Themostly used one is#include filename

    The #include directive results in the complete contents

    of the included file put in lieu of the directive. The included

    text is preprocessed again for eventual preprocessordirectives, e.g. other #include directives

    This directive has two forms:#include the preprocessor starts searching for the

    file from a predefined place, which usually stores the include fileswith the declarations of librarian elements

    #include filename the preprocessor starts searching for the

    file from another place, usually defined by the user, which storesthe include files of the users program

  • 8/4/2019 Introductory Course on C++

    103/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 103/209

    PreprocessorThis mechanism can be used to solve the described problem.

    For a .cpp file, a header file is created (.h). It consists of declarationsof the program elements that are defined in this .cpp file, and are tobe used in other files

    Note that a .h file should not contain the declarations of all elementsdefined in the .cpp file, but only those that are to be used in other

    files, i.e., the interface of the .cpp module. This way, encapsulation issupported at module level, although rudimentary and indirectly (notthrough a first-class language concept)

    Instead of an explicitdeclaration, #include is used

    A.cpp int a = 3; B.cpp#include A.h

    void g() {

    ... = a+3...}

    extern int a;A.h

    P

  • 8/4/2019 Introductory Course on C++

    104/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 104/209

    PreprocessorThe effect is that the compiler encounters the same codeas before, but the difference for the programmer issignificant: the declarations are now localized in onephysical place, making modifications easier and error-free

    As a result, when a .h file is modified, all .cpp files that

    include it must be recompiled (including transitiveinclusions), which assumes that the compiler compiles thedirectives in .h files, too (at least in order to create itssymbol table)

    The programming environment may help in reducing

    recompilation by the make procedure, which selectivelyand automatically recompiles only necessary .cpp files.However, the programmers should try their best to reducecompilation dependences between files, especially in largeprojects

    P

  • 8/4/2019 Introductory Course on C++

    105/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 105/209

    PreprocessorAnother directive is #define. It defines a symbol within

    the preprocessor (in its symbol table, which has nothing todo with the compilers one), and optionally replaces eachoccurrence of that symbol with the defined text (a macroreplacement):

    #define _A_h#define N 10#define max(a,b) (((a)>=(b))?(a):(b))

    int a[N];

    voidf (int a, int b){...

    int c = max(x/3,y+1);

    ...}

    Simply introduces a new symbol _A_h into the

    preprocessors symbol tableIntroduces a new symbol N into thepreprocessors symbol table. Every occurrenceof N in the text will be replaced with the text 10

    Introduces a new symbol max into thepreprocessors symbol table. Every occurrenceof max(?,?) in the text will be replaced with thegiven text, but the parameters will be replacedproperly (parameterized replacement)The compiler will see: int a[10];

    The compiler will see:

    int c = (((x/3)>=(y+1))?(x/3):(y+1));

    P

  • 8/4/2019 Introductory Course on C++

    106/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 106/209

    Preprocessor

    Header files often contain definitions of classes (whichdeclare the members):

    class Counter {

    public:Counter(int);

    int val();void inc();

    private:

    int counter;

    };

    Counter.h

    #include Counter.h

    Counter::Counter (int i) :

    counter(i) {}

    int Counter::val () {

    return counter;

    }...

    Counter.cpp

    The entire definition of the class Counter isneeded for the definitions of its memberfunctions.Caution: multiple definitions of a class are not allowed,

    even when completely identical

    P

  • 8/4/2019 Introductory Course on C++

    107/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 107/209

    PreprocessorProblem: what if a .h file witha class definition is includedseveral times in a .cpp file,either directly or indirectly?The compiler will encounter

    multiple class definitions andwill report an error!

    A.h

    B.h

    C.h

    D.h

    X.cpp

    The directives #ifdef/#endif and #ifndef/#endif

    process the enclosed text conditionally: the enclosed text is

    passed to the output of preprocessing only if the specifiedsymbol is (not) defined in the preprocessors symbol table:#ifdef _A_h... // some code that is compiled only if

    ... // the symbol _A_h is defined#endif

    P

  • 8/4/2019 Introductory Course on C++

    108/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 108/209

    PreprocessorThese directives are used: to solve the multiple-class-definition problem: enclose the code of

    each header file like this:#ifndef _A_h

    #define _A_h... // The code of the header file;

    // it will be transferred to the compiler// only the first time it is included

    #endif

    to enclose platform-dependent code:#ifdef Windows

    ... // Windows-dependent code

    #elif defined(Linux)... // Linux-dependent code

    #endif

  • 8/4/2019 Introductory Course on C++

    109/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 109

    Part III: Procedural Elements

    Operators and Expressions

    StatementsFunctions

  • 8/4/2019 Introductory Course on C++

    110/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 110

    Chapter 9: Operators and Expressions

    Expressions

    OperatorsLvalues

    Overview of Selected Operators

    Summary of Operators

    E i

  • 8/4/2019 Introductory Course on C++

    111/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 111/209

    ExpressionsAn expression is an element of a program that consists ofoperands (types, objects, literals, or functions) andoperations, and returns a result. The operations arespecified using the built-in operators

    An operation takes some operands and produces a result;the result may be used as an operand of anotheroperation, making compound expressions:a+b*ci + p->val()- b

  • 8/4/2019 Introductory Course on C++

    112/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 112/209

    ExpressionsThere is a default order of computation defined by: the priority of operators and

    their direction of grouping: left to right or right to left, in cases aresult of an operator is used as an operand of the same operator

    It can be modified by parentheses as usual (subexpressions):a+b*c // evaluated as a+(b*c);

    // * has a higher priority than +

    (a+b)*c

    cout

  • 8/4/2019 Introductory Course on C++

    113/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 113/209

    OperatorsC and C++ are very rich in operators. A major part of thecomputation in a typical C/C++ program is in operationswithin expressions

    A side effect occurs when a function/operation that returnsa result also modifies the state of its environment (e.g. thevalues of global variables or actual arguments/operands).In the classic theory of programming, side effects areconsidered harmful, since they reduce program readability,because functions, the focus of which is to produce aresult, have unexpected effects

    As opposed to this belief, many operators in C/C++ haveside effects: they modify their operands. For most of them,the side effect is their primary role!

    This is a result of the fact that C was dedicated to conciseand effective expressions, which became very popular

    Operators

  • 8/4/2019 Introductory Course on C++

    114/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 114/209

    OperatorsExample: the operator ++ increments the operand andreturns a value. It has two forms, prefix and postfix: ++operand: increment the operand, and return the new value

    operand++: increment the operand, and return its old value

    Similar holds for decrementing (--)

    (Hence the name of C++ - an incremented C; skeptics:what is the value of C++? :)a = i++; // a gets value of i before incrementb = --k; // b gets value of k after decrement

    Assignment is also an operator: except from assigning thevalue to its left operand (side effect!), it returns theassigned value as its result; it groups from right to left:a = b = c // evaluated as a=(b=c)

    x = y = f()+z // evaluated as x=(y=(f()+z))

    Operators

  • 8/4/2019 Introductory Course on C++

    115/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 115/209

    OperatorsThere are operators of compound assignment: a+=bmeans the same as a=a+b, except that the expression a iscomputed only once:a += b

    x -= y++u *= v+3

    w /= z--*p++ += 3 // evaluated as (*(p++))+=3;

    // not equivalent to *p++ = *p++ + 3,// because p is incremented twice in

    // the latter

    Lvalues

  • 8/4/2019 Introductory Course on C++

    116/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 116/209

    LvaluesApart from checking the types of operands an other thingswhen analyzing expressions, the compiler checks theconsistency of the lvalue property of operators operands

    Lvalue is a property of a program element; it is a Booleanproperty: an element is or is not an lvalue: a name of an object or a function is an lvalue for each built-in operator, it is defined whether it requires an

    operand that is an lvalue, and whether its result is or is not anlvalue

    In most cases, an lvalue is an element that refers to asound object in memory (but not a temporary object),although names of functions are also lvalues

    Lvalues

  • 8/4/2019 Introductory Course on C++

    117/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 117/209

    LvaluesIn most cases, the fact that an operator requires an lvaluemeans that the operator requires a sound object inmemory. All operators that have side effects on anoperand require that the operand is an lvalue

    The fact that an operator produces an lvalue as its result

    means that its result refers to a sound object and that itcan be used as an operand of another operator thatrequires an lvalue

    Examples:

    operator = requires an lvalue as its left operand (to produce theside effect), but not for its right operand; operators +, -, etc. donot result in lvalues:a = (b+c) // correct: a is an lvalue

    (a+b) = c // incorrect: a+b is not an lvalue

    Lvalues

  • 8/4/2019 Introductory Course on C++

    118/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 118/209

    Lvalues operator = produces an lvalue, too; it refers to the same object to

    which the left operand (as an lvalue) refers to:(a = b) = c // correct: a=b is an lvalue

    operator & requires an lvalue, but does not produce an lvalue; incontrast, operator * (pointer dereferencing) does not require anlvalue, but produces an lvalue, which refers to the object pointedto by the pointer operand:&a // correct: a is an lvalue&a = ... // incorrect: &a is not an lvalue&(a+3) // incorrect: a+3 is not an lvalue*(p+3) // correct: * does not require an lvalue*(p+3)=...// correct: *(p+3) is an lvalue

    operation a

  • 8/4/2019 Introductory Course on C++

    119/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 119/209

    LvaluesThe term lvalue has its origin in something that may bethe left operand of assignment, although all lvaluescannot be that

    A modifiable lvalue is an lvalue that is not a function,array, or a constant object. Only modifiable lvalues can be

    left operands of assignments:int a[N];a = b+3; // incorrect: a is not a modifiable lvalue

    voidf();f = ...; //incorrect: f is not a modifiable lvalue

    &f // correct: f is an lvalue, & does not require// a modifiable lvalue

    Overview of Selected Operators

  • 8/4/2019 Introductory Course on C++

    120/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 120/209

    Overview of Selected OperatorsFunction call is also an operator that results in a temporaryobject initialized with the return expression:expr(listOfArgs)

    There is an operation of constructing a temporaryanonymous object by explicit constructor call:Counter(0)

    Member access operators . and -> require an object and apointer to an object as their left operands, respectively,and a member name as their right operand. Their result isan lvalue only if the member is an lvalueIncrement (++) and decrement (--) operators requirenumeric operands. The result of the prefix form is, and ofthe postfix form is not an lvalue:++i = 5; // correct: ++i is an lvaluei-- = 5; // incorrect: i is not an lvalue

    Overview of Selected Operators

  • 8/4/2019 Introductory Course on C++

    121/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 121/209

    Overview of Selected OperatorsOperator sizeof returns the size of the operand. The

    operand (as an expression) is not evaluated at runtime,but only its type is determined at compile time. The unit ofmeasurement is sizeof(char)==1, not a byte! Twoforms: sizeof expr: sizeof (a+p->inc())

    sizeof(type): sizeof(Counter)

    Logic negation operator ! requires a numeric, a pointer, oran object that may be converted to a numeric or a pointeras its operand: if the operand is equal to 0 (symbolic value for pointers does not

    point to an object), which is treated as False, the result is 1 if the operand is not equal to 0 (symbolic value for pointers does

    point to an object), which is treated as True, the result is 0if (!p) ... // if p is not 0

    Overview of Selected Operators

  • 8/4/2019 Introductory Course on C++

    122/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 122/209

    Overview of Selected OperatorsArithmetic operators * (multiplication) and / (division)

    require numeric operands, and % (remainder) requiresintegral operands. If both operands are integral, the resultis integral; otherwise, the result is a floating-point:a%b // the remainder of division a/b

    Shift operators ab require integral operands

    and result in the binary representation ofa shifted b bitsleft/right; they do not have side-effectsRelational operators == (equal to), != (not equal to), ,= result in 1 (true) or 0 (false)

    Bit-wise operators & (and), | (or), ^ (exclusive or) requireintegral operands and operate bit-by-bitLogic operators && (and) and || (or) require numericoperators or pointers and return 0 (false) or 1 (true); theyconsider whether an operand is equal to 0 (False) or not

    (True)

    Overview of Selected Operators

  • 8/4/2019 Introductory Course on C++

    123/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 123/209

    Overview of Selected OperatorsOperator ?: is the only ternary operator:a?b:cFirst, a is evaluated. It must be of integral type or apointer. If its value is not equal to 0 (true), b is evaluatedand returned as the result. If the value ofa is equal to 0

    (false), c is evaluated and returned as the result. Note thatonly one of the operands is evaluated, never both

    Sequence operator (,) is a binary operator: a,b evaluatesa first, then b, and returns the result ofb as its result. It

    groups from left to right:a,b,c // evaluated as (a,b),c

    It is used when the syntax requires one expression, andyou want to do several operations:for (int i=0, j=0; i

  • 8/4/2019 Introductory Course on C++

    124/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 124/209

    Summary of OperatorsThe following table presents all operators in C++. Theoperators are grouped into groups of the same priority,while the groups are ordered by priority (decreasing). Thetable gives: the operator and its meaning

    the way of grouping: L: from left to right R: from right to left

    N/A: not applicable, because the result of the operator cannot be usedas an operand of the same operator

    lvalue: whether the result is an lvalue:

    Y: always N: never

    Y/N: depends on one of the operands

    usage: the way of usage; if an operand is expr, the operand is anexpression that does not need to have an lvalue result; if anoperand is lvalue, an lvalue expression is required as the operand

    Summary of Operators

  • 8/4/2019 Introductory Course on C++

    125/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 125/209

    Summary of Operators

    rator Meaning Grouping Lvalue Usage:: scope resolution L Y/N class_name:: member

    :: global name access Y/N :: name

    [] indexing L Y expr[expr]

    () function call L Y/N expr(list_of_expr)

    () object construction N type_name(list_of_expr). member access L Y/N expr. name-> indirect member access L Y/N expr-> name

    ++postfix increment L N lvalue++

    -- postfix decrement L N lvalue--

    ++ prefix increment R Y ++ lvalue

    -- prefix decrement R Y --lvaluesizeof size ofobject R N sizeofexpr

    sizeof size oftype R N sizeof(type)

    new dynamic object creation N newtypedelete dynamic object destruction N delete expr

    ~ bitwise complement R N ~expr! logic negation R N !expr

    - unary minus R N - expr

    + unary plus R N + expr

    & address of R N &lvalue

    * pointer dereferencing R Y *expr

  • 8/4/2019 Introductory Course on C++

    126/209

    Summary of Operators

  • 8/4/2019 Introductory Course on C++

    127/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 127/209

    Summary of Operators

    = simple assignment R Y lvalue = expr*= multiplication and

    assignmentR Y lvalue *= expr

    /= division and assignment R Y lvalue /= expr

    %= remainder and assignment R Y lvalue %= expr+= addition and assignment R Y lvalue += expr

    -= subtraction and assignment R Y lvalue -= expr

    >>= sift right and assignment R Y lvalue >>= expr

  • 8/4/2019 Introductory Course on C++

    128/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 128

    Chapter 10: Statements

    Basic Statements

    Conditional StatementsLoop Statements

    Other Statements

    Basic Statements

  • 8/4/2019 Introductory Course on C++

    129/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 129/209

    Basic StatementsStatements encompass some computation, but do not

    produce results as expressionsA declaration is a kind of a statement: a declaration mayoccur wherever a statement may occur (not only at thebeginning of a block)

    An expression terminated with ; is a statementA compound statement (a block) is a sequence of statementsenclosed in braces {}. The statements in a block areexecuted in order, sequentially. A block may occur wheneverone statement is expected, and you need more:

    { // start of a blockint a, c=0, d=3; // declaration as a statement;a=(c++)+d; // expression as a statement;int i=a; // declaration as a statement;i++; // expression as a statement;

    } // end of the block

    Conditional Statements

  • 8/4/2019 Introductory Course on C++

    130/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 130/209

    Conditional StatementsConditional statementif:if (expr) then-statement else else-statement

    the else else-statement part is optional

    if you need more than one statement, use a block

    the expr must result in a numeric, Boolean, or pointer value

    if the value of expr is not equal to 0 (true), then-statement isexecuted and the if statement is completed; otherwise, else-statement is executed, and the if statement is completed

    if (a++) b=a; // equivalent with if (a++ !=0)...

    if (c) a=c; // equivalent with if (c!=0)...

    else a=c+1;

    Conditional Statements

  • 8/4/2019 Introductory Course on C++

    131/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 131/209

    Conditional StatementsConditional statementswitch:

    switch (expr) {case const1 : list-of-statements1case const2 : list-of-statements2...case const

    n: list-of-statements

    n

    default : list-of-statementsd}

    the default part is optional expr must evaluate to an integral value

    the control passes directly to the case label that has the guard expri equalto the result of expr, or to the default part otherwise

    the execution is continued through the rest of the branches; if you wantonly one branch to be executed, use the break statement to exit the

    switch:switch (status) {case ok: commit();break;case failed: alert();break;case refused: retry();break;

    }

    Loop Statements

  • 8/4/2019 Introductory Course on C++

    132/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 132/209

    Loop StatementsLoop statementfor:for (init-statement expr1 ; expr2) statement the init-statement is an expression or a declaration; it always

    ends with a semicolon ;

    if you need more than one statement in statement, use a block

    the expr1 must result in a numeric, Boolean, or pointer value

    this is a while loop with an exit on topinit-statement

    statement

    expr1

    expr2

    ==0

    !=0

    init-statement, expr2, andstatement may be omitted

    expr1 is optional; 1 (true) is assumed if it

    is omitted

    Loop Statements

  • 8/4/2019 Introductory Course on C++

    133/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 133/209

    Loop StatementsExample: a usual counter loop in which the index i goes

    from 0 to n-1:for (int i = 0; i

  • 8/4/2019 Introductory Course on C++

    134/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 134/209

    Loop StatementsLoop statementwhile is a special case offor:

    while (expr) statement

    is equivalent tofor (;expr;) statement

    Loop statementdo-while is a loop with the exit at the

    end:do statementwhile (expr);is equivalent tostatement

    while (expr) statement

    Example:voidstrcopy (char* p, char* q) {while (*p++ = *q++); // Try to analyze this!

    }

    Other Statements

  • 8/4/2019 Introductory Course on C++

    135/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 135/209

    Other StatementsThe return statement returns from a function, with an

    optional result of the associated expression:return expr;

    The break statement breaks the first enclosing loop orswitch:

    while () { // Endless loop

    ...if (...)break;...

    }

    The continue statement skips the rest of a loop bodyand passes to the next loop iteration:for (...) {...if (...) continue;...

    }

    Other Statements

  • 8/4/2019 Introductory Course on C++

    136/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 136/209

    Other StatementsThe goto statement jumps to the specified label. Statements in

    functions may be labeled; labels have a function scope (visiblethroughout the entire function body, but not outside)

    The goto statement should not be used in structured programming,

    except for some structured constructs, such as exits from deeplynested loops:

    for (...) {...

    for (...) {

    ...for (...) {

    ...if

    (...)goto

    exit;...

    }

    }}

    exit: ...

  • 8/4/2019 Introductory Course on C++

    137/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 137

    Chapter 11: Functions

    Declaration and Invocation

    InliningDefault Argument Values

    Function Overloading

    Declaration and Invocation

  • 8/4/2019 Introductory Course on C++

    138/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 138/209

    Declaration and InvocationFunctions can be members of classes (i.e., have a class

    scope) or non-members (global functions)Functions are the only kind of subprograms in C/C++:procedures are special kinds of functions that return noresult (void as the return type)

    There is no static function nesting (nesting of functiondefinitions) as in Pascal, for example. Dynamic functionnesting (of function calls) is allowed, including recursion

    A function may, but need not have arguments. Argumentsare passed by value (C/C++), or by reference (C++)

    A declaration of a function that is not a definition does notneed to have names of arguments (desirable only forreadability purposes):int strcompare (char*,char*);voidstrcopy (char* to, char* from);

    Declaration and Invocation

  • 8/4/2019 Introductory Course on C++

    139/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 139/209

    Declaration and InvocationA function definition contains the function body, which is ablock. A function may return the result through thereturn statement:int Counter::inc () {

    return ++counter;

    }

    A function is called by the () operator. The result of a

    function call is a temporary object, created at the place ofinvocation, at the moment of function return, andinitialized with the result of the return expression. The

    semantics of this initialization are the same as any otherinitialization:a = ptrCounter->inc() + b;

    Declaration and Invocation

  • 8/4/2019 Introductory Course on C++

    140/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 140/209

    The type of a function is determined by: the number and types of formal arguments; T* and T[] are

    considered the same as types of arguments

    the type of the result; a function cannot return an array, only apointer to (the first element of) an array

    Pointers to functions may be defined. At runtime, a pointer

    to a function may be redirected to point to differentfunctions of the same type. A function may be called overa pointer to it. This concept is used to dynamically bindfunction calls (the traditional call-back mechanism that isobsolete in OO programming):

    int f(int,int), g(int,int);int (*p)(int,int) = &f;(*p)(5,3);p = g;p(7,3);

    p is a pointer to a function that acceptsan int and returns an int: int(*)(int,int)

    p points to f

    call the function pointed to by p; that is f

    the same as p = &g, because a function may beconverted into a pointer to the function

    the same as (*p)(7,3), because the function calloperator () may accept a function or a pointer to afunction as its first operand

    Declaration and Invocation

  • 8/4/2019 Introductory Course on C++

    141/209

    June 2003 Copyright (C) 2003 by Dragan Miliev 141/209

    When a function is called, the formal arguments are

    created as local automatic objects, initialized with theactual arguments. The semantics of this initialization arethe same as any other initiali