104
Faculty of Computer Science and Engineering Intensive Programming Lab CS-102L Ghulam Ishaq Khan Institute of Engineering Sciences and Technology, Topi.

C++ Part 2 Lab Manual GIKI

Embed Size (px)

DESCRIPTION

C++ Part 2 Lab Manual GIK InstituteTable of ContentsLAB 1 ............................................................................................................................................................. 3Review of CS101L & Arrays (1-D and 2-D) .................................................................................................... 3Lab 2: ........................................................................................................................................................... 13Pointers in C++ ............................................................................................................................................ 13Lab 3: ........................................................................................................................................................... 25Strings in C++............................................................................................................................................... 25Lab 4: ........................................................................................................................................................... 41Structures I ................................................................................................................................................. 41Lab 5: ........................................................................................................................................................... 48Structures II ................................................................................................................................................. 48Lab 6: ........................................................................................................................................................... 55Object Orientation in C++ I ........................................................................................................................ 55Lab 7: ........................................................................................................................................................... 64Object Orientation in C++ II ....................................................................................................................... 64Lab 8 ............................................................................................................................................................ 76Friend Function & Classes, This Pointer, and static Variables .................................................................... 76Lab 9 ............................................................................................................................................................ 85Operator Overloading ................................................................................................................................. 85Lab 10: ......................................................................................................................................................... 87Inheritance .................................................................................................................................................. 88Lab 11: ........................................................................................................................................................ 91Introduction to Polymorphism and Abstract Base Classes ......................................................................... 92Lab 12: ......................................................................................................................................................... 97File Handling in C++..................................................................................................................................... 97Faculty Faculty of Computer Science and Engineering Intensive Programming LabCS-102L Ghul

Citation preview

  • Faculty

    Faculty of Computer Science and Engineering

    Intensive Programming Lab

    CS-102L

    Ghulam Ishaq Khan Institute of Engineering

    Sciences and Technology, Topi.

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 2

    Table of Contents

    LAB 1 ............................................................................................................................................................. 3

    Review of CS101L & Arrays (1-D and 2-D) .................................................................................................... 3

    Lab 2: ........................................................................................................................................................... 13

    Pointers in C++ ............................................................................................................................................ 13

    Lab 3: ........................................................................................................................................................... 25

    Strings in C++............................................................................................................................................... 25

    Lab 4: ........................................................................................................................................................... 41

    Structures I ................................................................................................................................................. 41

    Lab 5: ........................................................................................................................................................... 48

    Structures II ................................................................................................................................................. 48

    Lab 6: ........................................................................................................................................................... 55

    Object Orientation in C++ I ........................................................................................................................ 55

    Lab 7: ........................................................................................................................................................... 64

    Object Orientation in C++ II ....................................................................................................................... 64

    Lab 8 ............................................................................................................................................................ 76

    Friend Function & Classes, This Pointer, and static Variables .................................................................... 76

    Lab 9 ............................................................................................................................................................ 85

    Operator Overloading ................................................................................................................................. 85

    Lab 10: ......................................................................................................................................................... 87

    Inheritance .................................................................................................................................................. 88

    Lab 11: ........................................................................................................................................................ 91

    Introduction to Polymorphism and Abstract Base Classes ......................................................................... 92

    Lab 12: ......................................................................................................................................................... 97

    File Handling in C++ ..................................................................................................................................... 97

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 3

    LAB 1

    Review of CS101L & Arrays (1-D and 2-D)

    1-Dimensional Arrays:

    Array basics

    Let's start by looking at a single variable used to store a person's age.

    Example 1.1:

    1: #include

    2:

    3: int main()

    4: {

    5: short age;

    6: age=23;

    7: cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 4

    11: }

    On line (5), an array of 4 short's is created. Values are assigned to each variable in the array on

    line (6) through line (9).

    Accessing any single short variable, or element, in the array is straightforward. Simply provide

    a number in square braces next to the name of the array. The number identifies which of the 4

    elements in the array you want to access.

    The program above shows that the first element of an array is accessed with the number 0 rather than

    1. Later in the tutorial, We'll discuss why 0 is used to indicate the first element in the array.

    Printing arrays

    Our program is a bit unrevealing in that we never print the array to screen. Here is the same program

    with an attempt to print the array to the screen:

    Example 1.3: 1: #include

    2:

    3: int main()

    4: {

    5: short age[4];

    6: age[0]=23;

    7: age[1]=34;

    8: age[2]=65;

    9: age[3]=74;

    10:

    11: cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 5

    Example 1.4:

    1: #include

    2:

    3: int main()

    4: {

    5: short age[4];

    6: age[0]=23;

    7: age[1]=34;

    8: age[2]=65;

    9: age[3]=74;

    10: cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 6

    The point here is that simply assigning one array to another will not copy the elements of the array. The

    hard question to answer is why the code doesn't compile. Later in the tutorial this example will be re-

    examined to explain why line (12) doesn't work. This code should not compile on either C or C++

    compilers. However, some older C++ compilers may ignore the ISO C++ standard and allow line 12 to

    compile. If it does compile on your C++ compiler, make a mental note that it is incorrect behavior.

    Let's try copying arrays using a technique similar to the technique used to print arrays (that is,

    one element at a time):

    Example 1.6:

    1: #include

    2:

    3: int main()

    4: {

    5: short age[4];

    6: short same_age[4];

    7:

    8: age[0]=23;

    9: age[1]=34;

    10: age[2]=65;

    11: age[3]=74;

    12:

    13: same_age[0]=age[0];

    14: same_age[1]=age[1];

    15: same_age[2]=age[2];

    16: same_age[3]=age[3];

    17:

    18: cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 7

    Copy second element

    Like printing arrays, there is no single statement in the language that says "copy an entire array into

    another array". The array elements must be copied individually.

    The technique used to copy one array into another is exactly the same as the technique used to

    copy 4 separate variables into 4 other variables. So what is the advantage to using arrays over

    separate variables?

    One significant advantage of an array over separate variables is the name. In our examples, using

    four separate variables requires 4 unique names. The 4 short variables in our array have the

    same name, age. The 4 short's in the array are identical except for an index number used to

    access them. This distinction allows us to shorten our code in a way that would be impossible

    with 4 variables, each with unique names:

    Example 1.7:

    1: #include

    2:

    3: int main()

    4: {

    5: short age[4];

    6: short same_age[4];

    7: int i, j;

    8: age[0]=23;

    9: age[1]=34;

    10: age[2]=65;

    11: age[3]=74;

    12:

    13: for(i=0; i

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 8

    Even though arrays give us some convenience when managing many variables of the same type,

    there is little difference between an array and variables declared individually. There is no single

    statement to copy an array, there is no single statement to print an array.

    If we want to perform any action on an array, we must repeatedly perform that action on each element

    in the array.

    2-Dimensional (2-D) Arrays

    So far we have explored arrays with only one dimension. It is also possible for arrays to have two or

    more dimensions. The two-dimensional array is also called a matrix.

    Here is a sample program that stores roll number and marks obtained by a student side by side in a

    matrix.

    Example 1.8:

    #include

    void main( )

    {

    int stud[4][2] ;

    int i,j ;

    for ( i = 0 ; i

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 9

    column which contains the roll no. or the first column which contains the marks. Remember the

    counting of rows and columns begin with zero. The complete array arrangement is shown below.

    Thus, 1234 is stored in stud[0][0], 56 is stored in stud[0][1] and so on. The above arrangement

    highlights the fact that a two- dimensional array is nothing but a collection of a number of one-

    dimensional arrays placed one below the other.

    In our sample program the array elements have been stored rowwise and accessed rowwise.

    However, you can access the array elements columnwise as well. Traditionally, the array elements

    are being stored and accessed rowwise; therefore we would also stick to the same strategy.

    Initializing a 2-Dimensional Array

    How do we initialize a two-dimensional array? As simple as this:

    int stud[4][2] = {

    { 1234, 56 },

    { 1212, 33 },

    { 1434, 80 },

    { 1312, 78 }

    } ;

    Or we can write like this also..

    int stud[4][2] = { 1234, 56, 1212, 33, 1434, 80, 1312, 78 } ;

    The above format work also but it is more difficult to read as compared to the first one. It is

    important to remember that while initializing a 2-D array it is necessary to mention the second

    (column) dimension, whereas the first dimension (row) is optional.

    Thus the declarations,

    int arr[2][3] = { 12, 34, 23, 45, 56, 45 } ;

    int arr[ ][3] = { 12, 34, 23, 45, 56, 45 } ;

    are perfectly acceptable, whereas,

    int arr[2][ ] = { 12, 34, 23, 45, 56, 45 } ;

    int arr[ ][ ] = { 12, 34, 23, 45, 56, 45 } ;

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 10

    would never work.

    Memory Map of a 2-Dimensional Array

    Let see the arrangement of the above student arrays in memory which contains roll number and marks.

    Example 1.9:

    This example will simply define an array of 2x3 and take input from user and prints scanned

    array.

    #include

    void main()

    {

    int arr[2][3],i,j;

    for(i=0;i

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 11

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 12

    would do for any regular function and, in its parentheses, specify that the argument is an array.

    Here is an example:

    #include

    using namespace std;

    void DisplayTheArray(double member[]) //function

    {

    for(int i = 0; i < 5; ++i)

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 13

    Lab 2:

    Pointers in C++

    In this lab we will be discussing pointers in detail. This is one of the most important

    concepts in C++ language. Pointers are used everywhere in C++, so if you want to use the C++

    language fully you have to have a very good understanding of pointers. They have to become comfortable

    for you.

    C++ uses pointers in three different ways:

    C++ uses pointers to create dynamic data structures -- data structures built up from blocks of

    memory allocated from the heap at run-time.

    C++ uses pointers to handle variable parameters passed to functions.

    Pointers in C++ provide an alternative way to access information stored in arrays. Pointer

    techniques are especially valuable when you work with strings. There is an intimate link between

    arrays and pointers in C++.

    To fully grasp the concept of pointers all you need is the concept and practice of pointers. Before

    talking about pointers lets talk a bit about computer memory.

    Computer Memory

    Essentially, the computer's memory is made up of bytes. Each byte has a number, an address,

    associated with it. The picture below represents several bytes of a computer's memory. In the

    picture, addresses 924 thru 940 are shown.

    Variable and Computer Memory

    A variable in a program is something with a name, the value of which can vary. The way the

    compiler handles this is that it assigns a specific block of memory within the computer to hold the value

    of that variable. The size of that block depends on the range over which the variable is allowed to vary.

    For example, on 32 bit PC's the size of an integer variable is 4 bytes. On older 16 bit PCs integers were 2

    bytes.

    Example 2.1:

    #include

    using namespace std;

    int main()

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 14

    {

    float fl=3.14;

    coutfl;

    return 0;

    }

    The output for this program will be

    How It Works: (Explanation)

    At line (4) in the program above, the computer reserves memory for fl. Depending on the

    computer's architecture, a float may require 2, 4, 8 or some other number of bytes. In our

    example, we'll assume that a float requires 4 bytes.

    When fl is used in line (5), two distinct steps occur:

    1. The program finds and grabs the address reserved for fl--in this example 924. 2. The contents stored at that address are retrieved

    The illustration that shows 3.14 in the computer's memory can be misleading. Looking at the diagram, it

    appears that "3" is stored in memory location 924, "." is stored in memory location 925, "1" in 926, and "4"

    in 927. Keep in mind that the computer actually converts the floating point number 3.14 into a set of ones

    and zeros. Each byte holds 8 ones or zeros. So, our 4 byte float is stored as 32 ones and zeros (8 per byte

    times 4 bytes). Regardless of whether the number is 3.14, or -273.15, the number is always stored in 4

    bytes as a series of 32 ones and zeros.

    Pointer:

    In C++ a pointer is a variable that points to or references a memory location in which data is stored. A

    pointer is a variable that points to another variable. This means that a pointer holds the memory address

    of another variable. Put another way, the pointer does not hold a value in the traditional sense; instead, it

    holds the address of another variable. A pointer "points to" that other variable by holding a copy of its

    address. Because a pointer holds an address rather than a value, it has two parts. The pointer itself holds

    the address and that address points to a value.

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 15

    Pointer declaration:

    A pointer is a variable that contains the memory location of another variable. The syntax is as

    shown below. You start by specifying the type of data stored in the location identified by the

    pointer. The asterisk tells the compiler that you are creating a pointer variable. Finally you give

    the name of the variable.

    Data_type *variable_name

    Such a variable is called a pointer variable (for reasons which hopefully will become clearer a

    little later). In C++ when we define a pointer variable we do so by preceding its name with an

    asterisk. In C++ we also give our pointer a type which, in this case, refers to the type of data

    stored at the address we will be storing in our pointer. For example, consider the variable

    declaration:

    int *ptr;

    int k;

    ptr is the name of our variable (just as k is the name of our integer variable). The '*' informs the

    compiler that we want a pointer variable, i.e. to set aside however many bytes is required to store

    an address in memory. The int says that we intend to use our pointer variable to store the address

    of an integer.

    Referencing Operator

    Suppose now that we want to store in ptr the address of our integer variable k. To do this we use

    the unary & operator and write:

    ptr = &k;

    What the & operator does is retrieve the address of k, and copies that to the contents of our

    pointer ptr. Now, ptr is said to "point to" k.

    Dereferencing operator

    The "dereferencing operator" is the asterisk and it is used as follows:

    *ptr = 7;

    will copy 7 to the address pointed to by ptr. Thus if ptr "points to" (contains the address of) k,

    the above statement will set the value of k to 7. That is, when we use the '*' this way we are

    referring to the value of that which ptr is pointing to, not the value of the pointer itself.

    Similarly, we could write:

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 16

    Here is graphical representation of Pointers.

    This Example will be very helpful in understanding the pointers. Understand it thoroughly how it

    works and then proceed.

    Example 2.2: #include

    using namespace std;

    int main ()

    {

    int firstvalue = 5, secondvalue = 15;

    int * p1, * p2;

    p1 = &firstvalue; // p1 = address of firstvalue

    p2 = &secondvalue; // p2 = address of secondvalue

    *p1 = 10; // value pointed by p1 = 10

    *p2 = *p1; // value pointed by p2 = value pointed by p1

    p1 = p2; // p1 = p2 (value of pointer is copied)

    *p1 = 20; // value pointed by p1 = 20

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 17

    Here in this code we are trying to play with memory and address of our variables for the better

    understanding of Pointers. On line number 5 we have two integer variables (i.e firstvalue and

    secondvalue). Both are assigned values of 5 and 15 respectively. On line number 6 we have two

    integer pointer variables (i.e p1 and p2). Both are assigned addresses of variables in line 5

    firstvalue and secondvalue respectively in line 7 and 8.

    firstvalue secondvalue

    758 754

    P1 P2

    In line 9 we see that *p1 is assigned value 10. This means that 10 should be copied in the

    variable, which is lying on an address to which p1 is pointing. We know that p1 is pointing to

    address of firstvalue. So line 9 results in assigning firstvalue the value of 10.

    firstvalue secondvalue

    758 754

    P1 P2

    In line 10 we encounter another assignment which says that value of variable pointed by p2

    should be replaced with the value of variable pointed by p1. So now secondvalue is assigned

    with value 10 as well.

    firstvalue secondvalue

    758 754

    P1 P2

    Well the assignment in line 11 is a bit confusing but very simple, all this assignment is doing is

    that now p1 is pointing to the same address as p2. So now we can say p1 and p2 are pointing at

    same address.

    firstvalue secondvalue

    5 15

    10 15

    10 10

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 18

    758 754

    P2

    P1

    In line 12 we see that *p1 is assigned value 20. This means that 10 should be copied in the

    variable, which is lying on an address to which p1 is pointing. We know that p1 is now pointing

    to address of secondvalue because in last line we pointed p1 to the address being pointed by p2.

    So line 12 results in assigning secondvalue the value of 20.

    firstvalue secondvalue

    758 754

    P2

    P1

    Now when we print the value of first value and second value it prints 10 for firstvalue and 20 for

    secondvalue; which is right due to the reasons explained above.

    Pointers: Pointing to the Same Address

    Here is a cool aspect of C++: Any number of pointers can point to the same address. For

    example, you could declare p, q, and r as integer pointers and set all of them to point to i, as shown here:

    int i;

    int *p, *q, *r;

    p = &i;

    q = &i;

    r = p;

    Note that in this code, r points to the same thing that p points to, which is i. You can assign pointers to

    one another, and the address is copied from the right-hand side to the left-hand side during the

    assignment. After executing the above code, this is how things would look:

    10 15

    10 20

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 19

    The variable i now has four names: i, *p, *q and *r. There is no limit on the number of pointers that can

    hold (and therefore point to) the same address.

    Pointer Arithmetics

    Like other variables pointer variables can be used in expressions. For example if p1 and p2 are

    properly declared and initialized pointers, then the following statements are valid.

    y=*p1 * *p2;

    sum=sum+*p1;

    z= 5 - *p2/*p1;

    *p2= *p2 + 10;

    C++ allows us to add integers to or subtract integers from pointers as well as to subtract one

    pointer from the other. We can also use short hand operators with the pointers p1+=; sum+=*p2;

    etc.,

    we can also compare pointers by using relational operators the expressions such as p1 >p2 ,

    p1==p2 and p1!=p2 are allowed.

    When an integer is added to, or subtracted from, a pointer, the pointer is not simply incremented

    or decremented by that integer, but by that integer times the size of the object to which the

    pointer refers. The number of bytes depends on the object's data type.

    /*Program to illustrate the pointer expression and pointer arithmetic*/

    Example 2.3:

    1:#include

    2:using namespace std;

    3: int main()

    4: {

    5:int *ptr1,*ptr2;

    6:int a,b,x,y,z;

    7:a=30;b=6;

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 20

    8:ptr1=&a;

    9:ptr2=&b;

    10:x=*ptr1 + *ptr2 - 6;

    11:y=6 - *ptr1 / *ptr2 +30;

    12: cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 21

    How it Works:

    This code explains all the rules related to arithematic of pointers. From line 1 to line 11, it is

    simply adding, subtracting and like manipulating with the pointers and variables. After all the

    manipulations and arithmetics it started printing values of pointers and other simple variables till

    line 12.

    a b

    7864 7868 7872 7876 7880 7884 7888

    ptr1 ptr2

    At line 18 it adds 1 to ptr1. Mostly people think that this will change the address of the pointer,

    but they are totally wrong. Remember pointer is pointing to an address. This addition does not

    change the address of the pointer, infact it changes the value of the pointer (not the value of the

    address pointer is pointing at.). ptr1 has the address of variable of variable a . So it adds 1 *4

    Btytes = 4bytes in the address of a which is stored in ptr1. Where as ptr2 points at the same value

    as before due to the assignment of line 19.

    a b

    7864 7868 7872 7876 7880 7884 7888

    ptr1 ptr2

    Line 20 prints the same value as was printed by the Line 16, because values of the variable was

    never changed, in fact ptr1s value which was address of a was changed. Now Line 21 will print

    30 6

    30 0XF 6

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 22

    the value stored in ptr1; which is address of memory 4 bytes ahead of variable a. Line 22 is

    trying to print the value at address, ptr1 is now pointing to, which was never assigned any value.

    Sending Pointers as Arguments to Functions

    When we pass pointers to some function, the addresses of actual arguments in the calling function are

    copied into the arguments of the called function. This means that using these addresses we would have

    an access to the actual arguments and hence we would be able to manipulate them. The following

    program illustrates this fact. Try this out:

    Example 2.4:

    #include

    void swap(int *,int *);

    using namespace std;

    int main( )

    {

    int a = 10, b = 20 ;

    int *p, *q;

    p = &a;

    q = &b;

    swap( p, q) ;

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 23

    A function pointer is a variable that stores the address of a function that can later be called through that function pointer. A useful technique is the ability to have pointers to functions. Their declaration is easy: write the declaration as it would be for the function, say int func(int a, float b); And simply put brackets around the name and a * in front of it: that declares the pointer. Because of precedence, if you don't parenthesize the name, you declare a function returning a pointer: /* function returning pointer to int */ int *func(int a, float b); //Wrong /* pointer to function returning int */ int (*func)(int a, float b); Once you've got the pointer, you can assign the address of the right sort of function just by using its name: like an array, a function name is turned into an address when it's used in an expression. You can call the function as: (*func)(1,2);

    Example 2.5

    #include using namespace std; void func(int); int main(){ void (*fp)(int); fp = func; (*fp)(1); cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 24

    The following assignment operation would be valid:

    mypointer = myarray;

    After that, mypointer and myarray would be equivalent and would have very similar properties. The

    main difference being that mypointer can be assigned a different address, whereas myarray can

    never be assigned anything, and will always represent the same block of 20 elements of type int.

    Therefore, the following assignment would not be valid:

    myarray = mypointer;

    Let's see an example that mixes arrays and pointers:

    Example 2.6:

    Output would be

    10, 20, 30, 40, 50,

    Pointers and arrays support the same set of operations, with the same meaning for both. The main

    difference being that pointers can be assigned new addresses, while arrays cannot. In the chapter about arrays, brackets ([]) were explained as specifying the index of an element of the

    array. Well, in fact these brackets are a dereferencing operator known as offset operator. They dereference the variable they follow just as * does, but they also add the number between brackets to

    the address being dereferenced. For example: a[5] = 0; // a [offset of 5] = 0

    *(a+5) = 0; // pointed by (a+5) = 0

    These two expressions are equivalent and valid, not only if a is a pointer, but also if a is an array.

    Remember that if an array, its name can be used just like a pointer to its first element. Note: Before doing your lab exercises run the examples. Exercises will be provided by the instructors in the lab.

    #include

    using namespace std;

    int main ()

    {

    int numbers[5];

    int * p;

    p = numbers; *p = 10;

    p++; *p = 20;

    p = &numbers[2]; *p = 30;

    p = numbers + 3; *p = 40;

    p = numbers; *(p+4) = 50;

    for (int n=0; n

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 25

    Lab 3:

    Strings in C++

    Handling of Character String A string is a sequence of characters. Any sequence or set of characters defined within double quotation symbols is a constant string. In C++ it is required to do some meaningful operations on strings they are:

    Reading string Displaying strings Combining or concatenating strings Copying one string to another. Comparing string & checking whether they are equal Extraction of a portion of a string

    Strings are stored in memory as ASCII codes of characters that make up the string appended with \0 (ASCII value of null). Normally each character is stored in one byte; successive characters are stored in successive bytes.

    Arrays of Characters

    Re-Introduction to Characters

    As it happens, strings are the most used items of computers. In fact, anything the user types is a string. It is up to you to convert it to another, appropriate, type of your choice. This is because calculations cannot be performed on strings. On the other hand, strings can be a little complex,

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 26

    which is why we wanted to first know how to use the other types and feel enough comfortable with them.

    Consider a name such as James. This is made of 5 letters, namely J, a, m, e, and s. Such letters, called characters, can be created and initialized as follows:

    char L1 = 'J', L2 = 'a', L3 = 'm', L4 = 'e', L5 = 's';

    To display these characters as a group, you can use the following:

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 27

    Because a character is initialized by including it in single-quotes, when creating an array of characters, to initialize it, you must also include each letter accordingly. A name such as James can be initialized as follows:

    char Name[6] = { 'J', 'a', 'm', 'e', 's' };

    As done with other arrays, each member of this array of characters can be accessed using its index. Here is an example:

    Example 3.1: #include using namespace std; int main() { char Name[6] = { 'J', 'a', 'm', 'e', 's' }; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 28

    J a m e s \0

    Streaming an Array of Characters

    Like any other variable, before using a string, you must first declare it, which is done by type the char keyword, followed by the name of the variable, followed by square brackets. When declaring the variable, if/since you do not know the number of characters needed for the string; you must still provide an estimate number. You can provide a value large enough to accommodate the maximum number of characters that would be necessary for the variable. For a person's name, this could be 20. For the title of a book or a web page, this could be longer. Here are examples:

    char Name[20]; char BookTitle[40]; char WebReference[80]; char WeekDay[4];

    To request the value of an array of characters, use the cin extractor just like you would proceed with any other variable, without the square bracket. Here is an example:

    char WeekDay[12]; cout > WeekDay;

    To display the value of an array of characters, use the cout extractor as we have used it with all other variables, without the square brackets. Here is an example:

    Example 3.2:

    #include using namespace std; int main() { char WeekDay[12]; char EndMe[] = "\n"; cout > WeekDay; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 29

    Today is Thursday

    Multidimensional Arrays of Characters

    C/C++ treats arrays of characters differently than it does the other arrays. For example, we have learned to declare a two-dimensional array of integers as follows:

    int Number[2][6] = { { 31, 28, 31, 30, 31, 30 }, { 31, 31, 30, 31, 30, 31 } };

    This variable is in fact two arrays and each array contains 6 integers. For a string, if you want to declare a two-dimension array of characters, the first dimension specifies the number of string in the variable. The second dimension specifies the number of characters that each string can hold. Here is an example:

    char StudentName[4][10] = { "Hermine", "Paul", "Gertrude", "Leon" };

    In this case, the StudentName variable is an array of 4 strings and each string can have a maximum of 9 characters (+1 for the null-terminated character). To locate a string on this variable, type the name of the array followed by its index, which is the index of the column. This means that the first string of the StudentName array can be accessed with StudentName[0]. The second would be StudentName[1], etc. This allows you to display each string on the cout extractor:

    Example 3.3:

    #include using namespace std; int main() { char StudentName[4][10] = { "Hermine", "Paul", "Gertrude", "Leon" }; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 30

    Student 1: Hermine Student 2: Paul Student 3: Gertrude Student 4: Leon

    When declaring and initializing such an array, the compiler does not need to know the number of strings in the array; it can figure it out on its own. Therefore, you can leave the first pair square brackets empty. If you are only declaring the array but cannot initialize, then you must specify both dimensions.

    Declaring a Pointer to Characters

    Pointers can be quite challenging to learn. The diagram should provide a better insight.

    The variable name (a pointer to a char) was located at address 0x007fe78. A pointer is 32 bits, ie. 4 bytes long and holds an address of the string which was 0x00408004. Addresses are always given in hexadecimal. The arrow shows what the pointer is pointing to, ie what is at the address in the pointer variable. At this address there were 13 bytes holding the string "David Bolton" with a terminating NULL, the same value as '\0'.

    Earlier, we declared an array as follows:

    char EndMe[] = "";

    The name of the variable is a pointer to the beginning of the array. For this reason, the name of the reason is sufficient to locate its value. Since in this case we do not specify the number of characters in the array, we can also just use a pointer to the array as the beginning of the array. The array can therefore be declared as follows:

    char *EndMe = "";

    Once again, to display the value of such an array, simply call its name on the cout extractor:

    #include using namespace std; int main()

    {

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 31

    char *EndMe = "";

    cout StudentName; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 32

    String Manipulation Functions

    Strings as Variables

    To create a variable of type string, simply:

    string fullName;

    Assignment, as always is the same:

    fullName = Aamir Hassan;

    Or like before, we could always combine the two with an initialization:

    string fullName = Aamir Hassan;

    Input/output with Strings

    I/O with Strings is as before:

    string fullName = ;

    cout > fullName; //get the name

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 33

    Relational String Operators

    == and != are same as before, but the others are not exactly like usage with numbers

    For instance, what exactly does it mean if one string is less than another?

    String I/O

    A common problem with reading strings from user input is that it could contain white

    spaces. Remember that white space (e.g. space, tab, newline) is treated as termination for

    cin.

    Take the following code for example:

    cout > fullname;

    String Processing

    In addition to giving us a new data type to hold strings, the string library offers many

    useful string processing methods.

    You can find most of them of them in the book, but here are a few useful ones.

    length () and size()

    This method returns the integer length of the string. The length() and size() are the same.

    Example:

    string s1 = Super!;

    //the integer 6 will be output.

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 34

    //the character m will be output.

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 35

    find(str, index)

    This method returns the integer index of the first occurrence of the specified string

    starting from the specified index.

    Returns -1 if pattern is not found.

    Example:

    string d = data data data;

    //5 is output

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 36

    Example:

    string transport = Cruise Ship;

    //outputs Ship

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 37

    int len;

    char str[15];

    strcpy(str, "Hello, world!");

    len = strlen(str);

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 38

    char D[25];

    Assume that the following statement has been executed before each of the remaining code fragments.

    Putting text into the source string: strcpy(S, "This is String 1."); Copying four characters from the beginning of S to D and placing a null at the end: strncpy(D, S, 4); D[4] = '\0'; Copying two characters from the middle of string S to D: strncpy(D, &S[5], 2); D[2] = '\0'; Copying the tail end of string S to D: strncpy(D, &S[8], 15);

    Which produces the same result as strcpy(D, &S[8]);

    Strcat ()

    strcat(ptr1, ptr2); where ptr1 and ptr2 are pointers to char

    strcat() is used to concatenate a null-terminated string to end of another string variable. This is equivalent to pasting one string onto the end of another, overwriting the null terminator. There is only one common use for strcat().

    Char S[25] = "world!"; Char D[25] = "Hello, ";

    Concatenating the whole string S onto D: strcat(D, S);

    N.B. If you fail to ensure that the source string is null-terminated, very strange and sometimes very ugly things may result.

    Strncat ()

    Syntax: strncat(ptr1, ptr2, n); where n is an integer and ptr1 and ptr2 are pointers to char

    strncat() is used to concatenate a portion of a possibly null-terminated string onto the end of another string variable. Care must be taken because some earlier implementations of C do not append the '\0' at the end of destination string. Given the following declarations, several things are possible, but only one is commonly used.

    Char S[25] = "world!";

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 39

    Char D[25] = "Hello, ";

    Concatenating five characters from the beginning of S onto the end of D and placing a null at the end:

    strncat(D, S, 5); strncat(D, S, strlen(S) -1);

    Both would result in D containing "Hello, world".

    N.B. If you fail to ensure that the source string is null-terminated, very strange and sometimes very ugly things may result.

    Strcmp ()

    Syntax: diff = strcmp(ptr1, ptr2); where diff is an integer and ptr1 and ptr2 are pointers to char

    strcmp() is used to compare two strings. The strings are compared character by character starting at the characters pointed at by the two pointers. If the strings are identical, the integer value zero (0) is returned. As soon as a difference is found, the comparison is halted and if the ASCII value at the point of difference in the first string is less than that in the second (e.g. 'a' 0x61 vs. 'e' 0x65) a negative value is returned; otherwise, a positive value is returned. Examine the following examples.

    char s1[25] = "pat"; char s2[25] = "pet";

    diff will have a negative value after the following statement is executed.

    diff = strcmp(s1, s2);

    diff will have a positive value after the following statement is executed.

    diff = strcmp(s2, s1);

    diff will have a value of zero (0) after the execution of the following statement, which compares s1 with itself.

    diff = strcmp(s1, s1);

    Strncmp ()

    Syntax: diff = strncmp(ptr1, ptr2, n); where diff and n are integers ptr1 and ptr2 are pointers to char

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 40

    strncmp() is used to compare the first n characters of two strings. The strings are compared character by character starting at the characters pointed at by the two pointers. If the first n strings are identical, the integer value zero (0) is returned. As soon as a difference is found, the comparison is halted and if the ASCII value at the point of difference in the first string is less than that in the second (e.g. 'a' 0x61 vs. 'e' 0x65) a negative value is returned; otherwise, a positive value is returned. Examine the following examples.

    char s1[25] = "pat"; char s2[25] = "pet";

    diff will have a negative value after the following statement is executed.

    diff = strncmp(s1, s2, 2);

    diff will have a positive value after the following statement is executed.

    diff = strncmp(s2, s1, 3);

    diff will have a value of zero (0) after the following statement.

    diff = strncmp(s1, s2, 1);

    Note: Before doing your lab exercises run the examples.

    Exercises will be provided by the instructors in the lab.

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 41

    Lab 4:

    Structures I

    Structure Declaration

    Structure Definition

    Structure Variables

    Structure Membership

    Arrays of structures

    STRUCTURES Arrays require that all elements be of the same data type. Many times it is necessary to group

    information of different data types. An example is a materials list for a product. The list typically

    includes a name for each item, a part number, dimensions, weight, and cost.

    C and C++ support data structures that can store combinations of character, integer floating point and

    enumerated type data. They are called a STRUCTS.

    Often multiple variables must be passed from one function to another, and often these variables have

    different data types. Thus it is useful to have a container to store various types of variables in. Structs

    allow the programmer to do just that

    A struct is a derived data type that consists of members that are each fundamental or derived data

    types.

    struct is used to declare a new data-type. Basically this means grouping variables together.

    Structures Definition

    Before a structure is created, it is necessary to define its overall composition. The format of the a structure is provided in the shape of a template or pattern which is then used to creatstructure variables of the same composition. The template is composed of the names and attributes of the data items to be included in the structure. The definition begins with the keyword structwhich is followed by a structure declaration consist of a set of user-defined data names and data types. These entries are separated by semicolons and enclosed within a pair of curly brackets. The definition ends with a semicolon. Thus, in general, the structure definition has the form

    struct tag-name{ type var-1; type-var-2; . . . . . . . . typevar-n;

    };

    wheretag-name is the user-supplied name that identified the structure template; type refers to any valid data type such as char, int, float, and so forth; and var-1, var-2, .var-n are user-defined variables

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 42

    names, arrays or pointers. The components of a structure are commonly referred to as members or field.

    Example 4.1:

    struct employee {

    char name[30]; int age; float salary;

    }

    Representation in Memory struct student { char name[20]; introll_no; }; struct student st;

    Structures Variables This code fragment illustrates how structure variables of the type structemployee are defined.

    struct employee{ char name[30]; int age; float salary;

    }; structemployee emp1, emp2, emp3;

    In the above example three structure variables emp1, emp2, and emp3 are created. Each structure consists of three members identified by name, age, and salary.

    OR

    roll_no

    . . .

    0 1 2 3 19

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 43

    struct employee {char name[30];

    int age; float salary;

    } emp1, emp2, emp3;

    Structure membership

    Members themselves are not variables they should be linked to structure variables in order to make them meaningful members.

    The link between a member and a variable is established using the member operator . i.e. dot operator or period operator. We access individual members of a structure with the .operator. For example to assign a value, we can enter:

    structx {int a; int b; int c; }; main() { struct x z; z.a = 10; // assigns member a of structure variable z value 10. z.b = 20; z.c = 30; }

    And to retrieve a value from a structure member:

    struct x { int a; int b; int c; }; main() { struct x z; z.a = 10; // Assigning a value to a member through a structure variable z.a++; // incrementing the member variable. cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 44

    }

    Example 4.2:

    structlib_books { char title[20]; char author[15]; int pages; float price; } book1,book2,book3;

    Now Book1.price is the variable representing the price of book1 and can be treated like any other ordinary variable. We can use scanf statement to assign values like

    cin>>book1.pages;

    Or we can assign variables to the members of book1

    strcpy(book1.title,basic); strcpy(book1.author,Balagurusamy); book1.pages=250; book1.price=28.50;

    Accessing Structure Variables example:

    Example 4.1:

    int main () { struct Library { int ISBN, copies, PYear; char bookName[30], AuthorName[30], PublisherName[30]; }; Library libraryVariable; LibraryVariable.ISBN = 1293; strcpy (libraryVariable.bookName, "Network Security"); strcpy (libraryVariable.AuthorName, "Martin"); strcpy (libraryVariable.PublisherName, "Waley"); libraryVariable.copies = 4; libraryVariable.PYear = 1998;

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 45

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 46

    struct x { int a; int b; int c; }; main() { struct x z; z.a = 10; z.a++; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 47

    cin>>n;

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 48

    Lab 5:

    Structures II

    Structures and functions

    Pointers to Structure

    Enumerations

    Bitwise Operations

    Structures and functions

    A structure can be passed as a function argument just like any other variable. This raises a few practical issues. Where we wish to modify the value of members of the structure, we must pass a pointer to that structure. This is just like passing a pointer to an int type argument whose value we wish to change. If we are only interested in one member of a structure, it is probably simpler to just pass that member. This will make for a simpler function, which is easier to re-use. Of course if we wish to change the value of that member, we should pass a pointer to it. When a structure is passed as an argument, each member of the structure is copied. This can prove expensive where structures are large or functions are called frequently. Passing and working with pointers to large structures may be more efficient in such cases

    Example 5.1: //Pass 'struct' elements to a function. int main () { struct { char name[20]; int age; } record; strcpy(record.name, "Joe Brown"); record.age = 21; display (record.name, record.age); return 0; } void display(char *name, int age) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 49

    // Purpose: Passing a copy of a structure to a function. #include struct record_format { char name[20]; int age;}; void display(struct record_format); using namespace std; int main () { struct record_format record; strcpy(record.name, "Joe Brown"); record.age = 21; display (record); cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 50

    A pointer to a structure must be initialized before it can be used anywhere in program. The address of a structure variable can be obtained by applying the address operator & to the variable. For example, the statement sptr1 = &emp1;

    Accessing Structure Members Using Arrow Operator

    The members of a structure can be accessed using an arrow operator. The arrow operator-> (consisting of minus sign (-) followed by the greater than (>) symbol). Using the arrow operator a structure member can be accessed by the expression sptr1->member-name Where sptr holds the address of a structure variable, and member-name is the name of a member belonging to the structure. For example, the values held by the members belonging to the structure emp1 are given by the expression: sptr1->name; sptr1->age; sptr1->salary; Using the pointers the members of the structure variable emp1 can be initialized asfollow: coutage; coutsptr1->salary; //Printing Structure fields cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 51

    Example 5.3: #include

    #include

    using namespace std;

    int main()

    {

    enum Days{Monday=13,Tuesday=8,Wednesday,Thursday};

    Days d1=Wednesday;

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 52

    Bitwise OR: The bitwise OR operator is a |:

    01001000 | 10111000 = ----------------- 11111000

    Bitwise Exclusive OR (XOR): The exclusive-or operation takes two inputs and returns a 1 if either one or the other of the inputs is a 1, but not if both are. That is, if both inputs are 1 or both inputs are 0, it returns 0. Bitwise exclusive-or, with the operator of a carrot, ^, performs the exclusive-or operation on each pair of bits. Exclusive-or is commonly abbreviated XOR.

    01110010 ^ 10101010 -------------- 11011000

    Suppose, we have some bit, either 1 or 0, that we'll call Z. When we take Z XOR 0, then we always get Z back: if Z is 1, we get 1, and if Z is 0, we get 0. On the other hand, when we take Z XOR 1, we flip Z. If Z is 0, we get 1; if Z is 1, we get 0:

    myBits ^ 0 : No change myBits ^ 1 : Flip

    Example 5.4:

    #include #include using namespace std; void binary(unsigned int u) { int upper; if(u < 256) upper = 128; else upper = 32768; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 53

    } cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 54

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 55

    Data Types, Objects, Classes and Instances

    Lab 6: Object Orientation in C++ I

    Data Types, Objects, Classes and Instances

    So far, we've learnt that C++ lets you create variables which can be any of a range of basic data types:

    int, long, double and so on. However, the variables of the basic types don't allow you to model real-

    world objects (or even imaginary objects) adequately. It's hard to model a box in terms of an int, for

    example; what we need is something that allows us to collect together the various attributes of an

    object. In C++, we can do this very easily using classes.

    You could define variables, length, breadth and height to represent the dimensions of the box and bind them together as members of a Box class, as follows:

    class Box { public: double length; double breadth; double height; };

    This code actually creates a new type, called Box. The keyword class defines Box as such, and the elements that make up this class are defined within the curly braces. Note that each line defining an element of the class is terminated by a semicolon, and that a semicolon also appears after the closing brace. The elements length, breadth and height are referred to as data members. At the top of the class definition, you can see we have put the keyword public - this just means that the data members are generally accessible from outside the class. You may, however, place restrictions on the accessibility of class members, and we'll see how this works a bit later in this chapter.

    With this definition of a new data type called Box, you can go ahead and define variables of this type just as you did with variables of the basic types:

    Box myBox; //Declare a variable myBox of type Box

    Once we've defined the class Box, the declaration of variables of this type is quite standard. The variable myBox here is also referred to as an object or an instance of the class Box.

    With this definition of a new data type called Box, you can go ahead and define variables of this type just as you did with variables of the basic types. You can then create, manipulate and destroy as many Box objects as you need to in your program. This means that you can model objects using classes and write your programs around them. So - that's object-oriented programming all wrapped up then?

    Well, not quite. You see, object-oriented programming (OOP) is based on a number of foundations (famously encapsulation, polymorphism and inheritance) and what we have seen so far doesn't quite fit the bill. Don't worry about what these terms mean for the moment - we'll be exploring these ideas in more detail as we learn more about what you can do with classes.

    First Class

    The notion of class was invented by an Englishman to keep the general population happy. It derives from the theory that people who knew their place and function in society would be much more secure and comfortable in life than those who did not. The famous Dane, Bjarne Stroustrup, who invented C++,

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 56

    undoubtedly acquired a deep knowledge of class concepts while at Cambridge University in England, and appropriated the idea very successfully for use in his new language.

    The idea of a class in C++ is similar to the English concept, in that each class usually has a very precise role and a permitted set of actions. However, it differs from the English idea, because class in C++ has largely socialist overtones, concentrating on the importance of working classes. Indeed, in some ways it is the reverse of the English ideal, because, as we shall see, working classes in C++ often live on the backs of classes that do nothing at all.

    Operations on Classes In C++ you can create new data types as classes to represent whatever kinds of objects you like. As you'll come to see, classes aren't limited to just holding data; you can also define member functions that act on your objects, or even operations that act between objects of your classes using the standard C++ operators. You can define the class Box, for example, so that the following statements work and have the meanings you want them to have:

    Box Box1; Box Box2; if(Box1 > Box2) // Fill the larger box Box1.Fill(); else Box2.Fill();

    You could also implement operations as part of the Box class for adding, subtracting or even multiplying boxes - in fact, almost any operation to which you could ascribe a sensible meaning in the context of boxes.

    We're talking about incredibly powerful medicine here and it constitutes a major change in the approach that we can take to programming. Instead of breaking down a problem in terms of what are essentially computer-related data types (integer numbers, floating point numbers and so on) and then writing a program, we're going to be programming in terms of problem-related data types, in other words classes. These classes might be named Employee, or Cowboy, or Cheese or Chutney, each defined specifically for the kind of problem that you want to solve, complete with the functions and operators that are necessary to manipulate instances of your new types.

    Program design now starts with deciding what new application-specific data types you need to solve the problem in hand and writing the program in terms of operations on the specifics that the problem is concerned with, be it Coffins or Cowpokes.

    Terminology

    Let's summarize some of the terminology that we will be using when discussing classes in C++:

    A class is a user-defined data type

    Object-oriented programming is the programming style based on the idea of defining your own data types as classes

    Declaring an object of a class is sometimes referred to as instantiation because you are creating an instance of a class

    Instances of a class are referred to as objects

    The idea of an object containing the data implicit in its definition, together with the functions that operate on that data, is referred to as encapsulation

    When we get into the detail of object-oriented programming, it may seem a little complicated in places, but getting back to the basics of what you're doing can often help to make things clearer, so always keep in mind what objects are really about. They are about writing programs in terms of the objects that are

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 57

    specific to the domain of your problem. All the facilities around classes in C++ are there to make this as comprehensive and flexible as possible. Let's get down to the business of understanding classes.

    Understanding Classes

    A class is a data type that you define. It can contain data elements, which can either be variables of the basic types in C++ or other user-defined types. The data elements of a class may be single data elements, arrays, pointers, arrays of pointers of almost any kind or objects of other classes, so you have a lot of flexibility in what you can include in your data type. A class can also contain functions which operate on objects of the class by accessing the data elements that they include. So, a class combines both the definition of the elementary data that makes up an object and the means of manipulating the data belonging to individual instances of the class.

    The data and functions within a class are called members of the class. Funnily enough, the members of a class that are data items are called data members and the members that are functions are called function members or member functions. The member functions of a class are also sometimes referred to as methods, although we will not be using this term.

    When you define a class, you define a blueprint for a data type. This doesn't actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object. It's much the same as if you wrote a description of the basic type double. This wouldn't be an actual variable of type double, but a definition of how it's made up and how it operates. To create a variable, you need to use a declaration statement. It's exactly the same with classes, as you will see.

    Defining a Class

    Let's look again at the class we started talking about at the start of the chapter - a class of boxes. We defined the Box data type using the keyword class as follows:

    class Box { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches };

    The name that we've given to our class appears following the keyword and the three data members are defined between the curly braces. The data members are defined for the class using the declaration statements that we already know and love, and the whole class definition is terminated with a semicolon. The names of all the members of a class are local to a class. You can therefore use the same names elsewhere in a program without causing any problems.

    Access Control in a Class

    The keyword public looks a bit like a label, but in fact it is more than that. It determines the

    access attributes of the members of the class that follow it. Specifying the data members as public means that these members of an object of the class can be accessed anywhere within the scope of the class object. You can also specify the members of a class as private or protected. In fact, if you omit the access specification altogether, the members have the default attribute, private. We shall look into the effect of these keywords in a class definition a bit later.

    Remember that all we have defined so far is a class, which is a data type. We haven't declared any objects of the class. When we talk about accessing a class member, say height, we're talking about accessing the data member of a particular object, and that object needs to be declared somewhere.

    Declaring Objects of a Class

    We declare objects of a class with exactly the same sort of declaration that we use to declare objects of basic types. We saw this at the beginning of the chapter. So, we could declare objects of our class, Box, with these statements:

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 58

    Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box

    Both of the objects Box1 and Box2 will, of course, have their own data members. This is illustrated here:

    The object name Box1 embodies the whole object, including its three data members. They are not initialized to anything, however - the data members of each object will simply contain junk values, so we need to look at how we can access them for the purpose of setting them to some specific values.

    Accessing the Data Members of a Class

    The data members of objects of a class can be referred to using the direct member access operator (.). So, to set the value of the data member height of the object Box2 to, say, 18.0, we could write this assignment statement: Box2.height = 18.0; // Setting the value of a data member

    We can only access the data member in this way, in a function outside the class, because the member height was specified as having public access. If it wasn't defined as public, this statement would not compile. We'll see more about this shortly.

    Try It Out - Your First Use of Classes

    Let's have a go at creating a Box class and setting the values of it's data members. We'll try it out in the following console application:

    Example 6.1:

    // Creating and using boxes #include using namespace std; class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches }; int main(void) { Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box double volume = 0.0; // Store the volume of a box here Box1.height = 18.0; // Define the values Box1.length = 78.0; // of the members of Box1.breadth = 24.0; // the object Box1 Box2.height = Box1.height - 10; // Define Box2 Box2.length = Box1.length/2.0; // members in Box2.breadth = 0.25*Box1.length; // terms of Box1

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 59

    // Calculate volume of Box1 volume = Box1.height * Box1.length * Box1.breadth; cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 60

    Here, we've used the type name between parentheses, rather than a specific object name - this is standard syntax for the sizeof operator.

    This example has demonstrated the mechanism for accessing the public data members of a class. It also shows that they can be used in exactly the same way as ordinary variables.

    Using Pointers to Objects

    As you might expect, we can create a pointer to variable of a Box type. The declaration for this is just what you might expect:

    Box* pBox = &aBox

    Assuming we have already declared an object, aBox, of type Box, then this line simply declares a pointer to type Box and initializes it with the address of aBox. We could now access the members of aBox through the pointer pBox, using statements like this:

    (*pBox).length = 10;

    The parenthesis to de-reference the pointer here are essential, since the member access operator takes precedence over the de-reference operator. Without the parenthesis, we would be attempting to treat the pointer like an object and to de-reference the member, so the statement would not compile.

    This method of accessing a member of the class via a pointer looks rather clumsy. Since this kind of operation crops up a lot in C++, the language includes a special operator to enable you to express the same thing in a much more readable and intuitive form. It is called the indirect member access operator, and it is specifically for accessing members of an object through a pointer. We could use it to re-write the statement to access the length member of aBox through the pointer pBox:

    pBox->length = 10;

    The operator looks like a little arrow and is formed from a minus sign followed by the symbol for 'greater than'. It's much more expressive of what's going on, isn't it? We'll be seeing a lot more of this operator as we go along and learn more about classes. We're now ready to break new ground by taking a look at member functions of a class.

    Member Functions of a Class

    A member function of a class is a function that has its definition or its prototype within the class definition. It operates on any object of the class of which it is a member, and has access to all the

    members of a class for that object.

    Try It Out - Adding a Member Function to Box

    To see how accessing the members of the class works, let's create an example extending the Box class to

    include a member function.

    Example 6.2:

    // Calculating the volume of a box with a member function #include using namespace std; class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Function to calculate the volume of a box double Volume(void) {

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 61

    return length * breadth * height; } }; int main(void) { Box Box1; // Declare Box1 of type Box Box Box2; // Declare Box2 of type Box double volume = 0.0; // Store the volume of a box here Box1.height = 18.0; // Define the values Box1.length = 78.0; // of the members of Box1.breadth = 24.0; // the object Box1 Box2.height = Box1.height - 10; // Define Box2 Box2.length = Box1.length/2.0; // members in Box2.breadth = 0.25*Box1.length; // terms of Box1 volume = Box1.Volume(); // Calculate volume of Box1 cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 62

    Note that the Box object is still the same number of bytes. Adding a function member to a class doesn't affect the size of the objects. Obviously, a member function has to be stored in memory somewhere, but there's only one copy regardless of how many class objects have been declared, and it isn't counted when the operator sizeof produces the number of bytes that an object occupies.

    The names of the class data members in the member function automatically refer to the data members of the specific object used to call the function, and the function can only be called for a particular object of the class. In this case, this is done by using the direct member access operator (.) with the name of an object.

    If you try to call a member function without specifying an object name, your program will not

    compile.

    Positioning a Member Function Definition

    A member function definition need not be placed inside the class definition. If you want to put it outside the class definition, you need to put the prototype for the function inside the class. If we rewrite the previous class with the function definition outside, then the class definition looks like this:

    class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches double Volume(void); // Member function prototype };

    Now we need to write the function definition, but there has to be some way of telling the compiler that the function belongs to the class Box. This is done by prefixing the function name with the name of the class and separating the two with the scope resolution operator, ::, which is formed from two successive colons. The function definition would now look like this:

    // Function to calculate the volume of a box double Box::Volume(void) { return length * breadth * height; }

    It will produce the same output as the last example. However, it isn't exactly the same program. In the second case, all calls to the function are treated in the way that we're already familiar with. However, when we defined the function within the definition of the class in Ex6_02.cpp, the compiler implicitly treated the function as an inline function.

    Inline Functions

    With an inline function, the compiler tries to expand the code in the body of the function in place of a call to the function. This avoids much of the overhead of calling the function and, therefore, speeds up your code. This is illustrated here:

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 63

    Of course, the compiler takes care of ensuring that expanding a function inline doesn't cause any

    problems with variable names or scope.

    The compiler may not always be able to insert the code for a function inline (such as with recursive functions or functions for which you have obtained an address), but generally it will work. It's best used for very short, simple functions, such as our function Volume(), because they will execute faster and will not significantly increase the size of the executable module.

    With the function definition outside of the class definition, the compiler treats the function as a normal function and a call of the function will work in the usual way. However, it's also possible to tell the compiler that, if possible, we would like the function to be considered as inline. This is done by simply placing the keyword inline at the beginning of the function header. So, for our function, the definition would be as follows:

    // Function to calculate the volume of a box inline double Box::Volume(void) { return length * breadth * height; }

    With this definition for the function, the program would be exactly the same as the original. This allows you to put the member function definitions outside of the class definition, if you so choose, and still retain the speed benefits of inlining.

    You can apply the keyword inline to ordinary functions in your program that have nothing to do with classes and get the same effect. However, remember that it's best used for short, simple functions.

    We now need to understand a little more about what happens when we declare an object of a class.

    Note: Before doing your lab exercises run the examples. Exercises will be provided by the instructors in the lab.

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 64

    Lab 7:

    Object Orientation in C++ II

    Class Constructors

    In the previous program, we declared our Box objects, Box1 and Box2, and then laboriously

    worked through each of the data members for each object, in order to assign an initial value to

    it. This is unsatisfactory from several points of view. First of all, it would be easy to overlook

    initializing a data member, particularly in the case of a class which had many more data

    members than our Box class. Initializing the data members of several objects of a complex class

    could involve pages of assignment statements. The final constraint on this approach arises

    when we get to defining data members of a class that don't have the attribute public - we

    won't be able to access them from outside the class anyway. There has to be a better way, and

    of course there is - it's known as the class constructor.

    What is a Constructor?

    A class constructor is a special function in a class that is called when a new object of the class is

    declared. It therefore provides the opportunity to initialize objects as they are created and to

    ensure that data members only contain valid values.

    You have no leeway in naming a class constructor - it always has the same name as the class in

    which it is defined. The function Box(), for example, is a constructor for our Box class. It also

    has no return type. It's wrong to specify a return type for a constructor; you must not even write

    it as void. The primary function of a class constructor is to assign initial values to the data

    elements of the class, and no return type is necessary or, indeed, permitted.

    Try It Out - Adding a Constructor to the Box class

    Let's extend our Box class to incorporate a constructor.

    Example 7.1:

    // Using a constructor #include using namespace std; class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Constructor definition Box(double lv, double bv, double hv) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 65

    // Function to calculate the volume of a box double Volume() { return length * breadth * height; } }; int main(void) { Box Box1(78.0,24.0,18.0); // Declare and initialize Box1 Box CigarBox(8.0,5.0,1.0); // Declare and initialize CigarBox double volume = 0.0; // Store the volume of a box here volume = Box1.Volume(); // Calculate volume of Box1 cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 66

    CigarBox has a volume looking suspiciously like the product of its dimensions, which is quite a

    relief.

    The Default Constructor

    Try modifying the last example by adding the declaration for Box2 that we had previously: Box Box2; // Declare Box2 of type Box

    Here, we've left Box2 without initializing values. When you rebuild this version of the program,

    you'll get the error message:

    error C2512: 'Box': no appropriate default constructor available

    This means that the compiler is looking for a default constructor for Box2, either one that needs

    no arguments, because none are specified in the constructor definition, or one whose arguments

    are all optional, because we haven't supplied any initializing values for the data members. Well,

    this statement was perfectly satisfactory in Ex6_02.cpp, so why doesn't it work now?

    The answer is that the previous example used a default constructor that was supplied by the

    compiler, because we didn't supply one. Since in this example we did supply a constructor, the

    compiler assumed that we were taking care of everything and didn't supply the default. So, if you

    still want to use declarations for Box objects which aren't initialized, you have to include the

    default constructor yourself. What exactly does the default constructor look like? In the simplest

    case, it's just a constructor that accepts no arguments, it doesn't even need to do anything: Box() // Default constructor {} // Totally devoid of statements

    Try It Out - Supplying a Default Constructor

    Let's add our version of the default constructor to the last example, along with the declaration for

    Box2, plus the original assignments for the data members of Box2. We must enlarge the default

    constructor just enough to show that it is called. Here is the next version of the program:

    // Supplying and using a default constructor #include using namespace std; class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Constructor definition Box(double lv, double bv, double hv) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 67

    return length * breadth * height; } }; int main(void) { Box Box1(78.0,24.0,18.0); // Declare and initialize Box1 Box Box2; // Declare Box2 - no initial values Box CigarBox(8.0,5.0,1.0); // Declare and initialize CigarBox double volume = 0.0; // Store the volume of a box here volume = Box1.Volume(); // Calculate volume of Box1 cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 68

    include the prototype of a function in the class definition, the default parameter value should go

    in the prototype.

    If we decided that the default size for a Box object was a unit box with all sides of length 1, we

    could alter the class definition in the last example to this:

    class Box // Class definition at global scope { public: double length; // Length of a box in inches double breadth; // Breadth of a box in inches double height; // Height of a box in inches // Constructor definition Box(double lv = 1.0, double bv = 1.0, double hv = 1.0) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 69

    double height; // Height of a box in inches

    // Constructor definition Box(double lv=1.0, double bv=1.0, double hv=1.0) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 70

    cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 71

    #include using namespace std; class Box // Class definition at global scope { public: // Constructor definition Box(double lv=1.0, double bv=1.0, double hv=1.0) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 72

    We could also put functions into the private section of a class. In this case, they can only be

    called by other member functions. If you put the function Volume() in the private section, you

    will get a compiler error from the statements that attempt to use it in the function main(). If you

    put the constructor in the private section, you won't be able to declare any members of the

    class.

    The above example generates this output:

    This demonstrates that the class is still working satisfactorily, with its data members defined as

    having the access attribute private. The major difference is that they are now completely

    protected from unauthorized access and modification.

    If you don't specify otherwise, the default access attribute which applies to members of a class is

    private. You could, therefore, put all your private members at the beginning of the class

    definition and let them default to private by omitting the keyword. However, it's better to take the

    trouble to explicitly state the access attribute in every case, so there can be no doubt about what

    you intend.

    Of course, you don't have to make all your data members private. If the application for your

    class requires it, you can have some data members defined as private and some as public. It

    all depends on what you're trying to do. If there's no reason to make members of a class public,

    it is better to make them private as it makes the class more secure. Ordinary functions won't be

    able to access any of the private members of your class.

    Accessing private Class Members On reflection, declaring all the data members of a class as private might seem rather extreme.

    It's all very well protecting them from unauthorized modification, but that's no reason to keep

    their values a secret. What we need is a Freedom of Information Act for private members.

    You don't need to start writing to your state senator to get it - it's already available to you. All

    you need to do is to write a member function to return the value of a data member. Look at this

    member function for the class Box: inline double Box::GetLength(void) { return length; }

    Just to show how it looks, this has been written as a member function definition which is external

    to the class. We've specified it as inline, since we'll benefit from the speed increase, without

    increasing the size of our code too much. Assuming that you have the declaration of the function

    in the public section of the class, you can use it by writing this statement: len = Box2.GetLength(); // Obtain data member length

    All you need to do is to write a similar function for each data member that you want to make

    available to the outside world, and their values can be accessed without prejudicing the security

    of the class. Of course, if you put the definitions for these functions within the class definition,

    they will be inline by default.

    The Default Copy Constructor Suppose we declare and initialize a Box object Box1 with this statement:

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 73

    Box Box1(78.0, 24.0, 18.0);

    We now want to create another Box object, identical to the first. We would like to initialize the

    second Box object with Box1.

    Try It Out - Copying Information Between Instances We can try this out with the main() function which follows:

    Example 7.3:

    // Initializing an object with an object of the same class #include using namespace std; class Box // Class definition at global scope { public: // Constructor definition Box(double lv=1.0, double bv=1.0, double hv=1.0) { cout

  • CS102L: Intensive Programming Lab

    FCS&E, GIK Institute Topi, Pakistan Page 74

    Clearly, the program is working as we would want, with both boxes having the same volume.

    However, as you can see from the output, our constructor was called only once for the creation

    of Box1. But how was Box2 created? The mechanism is similar to the one that we experienced