C++-programming Part 2 Hannu Laine Copyright Hannu Laine Inline functions When inline function is called, compiler does not generate a real call (pushing parameters onto the stack and so on). The function call is replaced by function body and it manipulates the real arguments directly. Inline functions in C++ are used instead of macros with parameters in C. Inline functions are better, because compiler makes normal type checking for parameters. It is also possible to make member functions of a class inline. Only short and simple functions should be made inline. If function body is defined in class definition it is inline by default. ---------See separate example of inline function min_inline on the following pages (function returns a minimum (smaller) of two integers. HL 1 Inline functions The following simple program demonstrates inline functions. Program was compiled and the result assembly program is shown on the next page to see the difference in the overheads of the inline and ordinary function calls. Instructions needed to complete the “ordinary” function are in red and corresponding instructions of inline function are in blue font. #include <iostream.h> inline int min_inline(int a,int b) { return a<b ? a : b; } int min_ordinary(int a,int b) { return a<b ? a : b; } //Main program int main(void) { int number1 = 4, number2 = 3; int min1, min2; min1 = min_inline(number1, number2); min2 = min_ordinary(number1, number2); cout << min1; cout << min2; } HL 2 Inline functions do not have function call overhead Function implementation of min_ordinary @min_ordinary$qii proc near ;int min_ordinary(int a,int b) { return a<b ? a : b; } push ebp mov ebp,esp mov edx,dword ptr [ebp+12] mov eax,dword ptr [ebp+8] @1:cmp edx,eax jg short @4 mov eax,edx @4:pop ebp ret @min_ordinary$qii endp Function implementation of main _main proc near …. @6:mov eax,4 ; eax is number1 mov edx,3 ;edx is number2 ;min1 = min_inline(number1, number2); cmp edx,eax jle short @7 mov ebx,eax jmp short @8 @7:mov ebx,edx ; ebx is min1 ;min2 = min_ordinary(number1, number2); @8:push edx push eax call @min_ordinary$qii add esp,8 mov esi,eax ; esi is min2 ;cout << min1 mov eax,ebx HL … ret _main endp 3 Defining structure type in C and C++ Option 1. (ANSI C) typedef struct { char name[31]; int age; float weight; } Tperson; Tperson person; Option 2. (K&R, Kernighan & Ritchie) struct person_tag { char name[31]; int age; float weight; }; struct person_tag person; Option 3. (C++) struct Tperson { char name[31]; int age; float weight; }; Tperson person; HL 4 Object oriented programming languages Simula 67 Smalltalk (early 1970s) C++ (early 1980s) Java (early 1990s) ----Eiffel Oberon HL 5 Basic idea ”Emphasis from verbs to nouns” It’s a natural way for people to ”think in objects”. Programming is identifying objects in the problem space and implementing them using programming language. All tasks are delegated to objects that are responsible for completing them. Program consists of objects interacting with each other Objects provide services HL 6 Advantages Programs are: Clearer and easier to read Easier to maintain Code is more easily reusable HL 7 Basic rules to define objects Objects should correspond real word objects Responsibility area should be simple and compact All actions should be delegated to objects Don’t mix responsibilities Keep responsibility areas as general as possible to guarantee reuse. We use an example problem to demonstrate the difference between C++ (object oriented) and C (procedural) program. The problem description is as follows: Write a program that generates 100 random numbers between [0, 1) and counts how many of them are less that 0.5 and how many greater than or equal to 0.5. You can see the C-program on the next page. The C++-program is shown on the page 11. HL 8 Random number generator problem (C) // This is C-version. “Procedural thinking” is used. #include <stdlib.h> #include <time.h> #include <stdio.h> void main() { int counter1, counter2, i; srand(time(NULL)); float x; counter1 = 0; counter2 = 0;i = 0; while (i < 100) { x = (float)rand() / RAND_MAX; if ( x < 0.5) counter1++; else counter2++; i++; } printf(“%d\n”, counter1); printf(“%d\n”, counter1); } HL 9 Random number generator problem (C++) // This is C++-version. Object oriented approach is used #include <iostream> using namespace std; void main(void) { Dice dice; Counter counter1, counter2, i; Inspector inspector; dice.initialize(); counter1.reset(); counter2.reset(), i.reset(); inspector.setLimits(0, 0.5); while (i.getCount() < 100) { if (inspector.isInLimits(dice.roll())) counter1.increment(); else counter2.increment(); i.increment(); } cout << counter1.getCount(); cout << counter2.getCount(); } // And then we need to implement the classes Dice, Counter and Inspector. HL 10 Why it is better to use Counter instead of int? We have moved to use objects in C++. For example, we don’t use anymore directly int as a counter. This makes a program longer and even slower. What are the advantages? Int does not behave like a counter by default. We have the following problems when using int as a counter: 1. The programmer can forget to initialize the int counter or he/she can initialize it with a wrong value. In C++ the constructor of Counter class initializes the counter always with a correct value automatically. 2. When counter is incremented too many times, the results are totally useless. The upper limit is not “natural” because it is MAX_INT. In C++ we can make the counter to round up and start from the beginning again when reasonable upper limit (for example 999999999) has been reached. 3. The programmer can increment the int counter by a “wrong” value. In C++ we make the int data member private so that it is not possible use it in the wrong way. The counter can then be used only by the fully defined, carefully designed and perfectly tested interface. For example incrementing is done with the member function increment. HL 11 Moving from C to C++ To move from the C-program to C++-program (from a procedural programming to an object oriented programming) we need to learn many new concepts. Some of these concepts are mentioned on the following page. The most important concepts are class and object. The simple example program on the page 13 is used to demonstrate some of these concepts. Actually we can think that a class is a C++-way to implement ADT. There is a separate transparent that illustrates a difference between ADT:s implemented using structures and functions in C and a class in C++. The operation functions are “are moved inside the data type” and they are called member functions or methods. HL 12 Key terms Object (variable) Class (type) Encapsulation Interface Implementation Attribute / Instance variable / Data member Member function / Operation / Method Private and public members Class variables / static members Inheritance Polymorphism Virtual functions Late binding (early binding) Templates Generic programming HL 13 Simple class example (Class Person) //class definitions class Person { public: void read(); void print(); void getOlder(int years); private: char name[30]; int age; }; //Application void main(void) { Person matti, maija; matti.read(); matti.getOlder(1); matti.print() } //Operation function implementations void Person::read() { cout << "\nEnter name "; cin >> name; cout << "\nEnter age"; cin >> age; } void Person::print() { cout << "\nPersonal data is "; cout << name; cout << age;; } void Person::getOlder(int years) { age = age + years; } 14 More about keyword private The private member of the class can be accessed in the member function whether the object is target object, parameter object or local variable. Example: class Time { public: Time diff(Time t2); private: int hour; int min; }; //Application void main(void) { Time time1, time2, difference; difference = time1.diff(time2); } //Operation function implementations Time Time::diff( Time t2) { Time aux; int dmin, t1min, t2min; t1min = hour * 60 + min; // target object t2min = t2.hour * 60 + t2.min; // parameter object dmin = t1min – t2min; aux.hour = dmin / 60; // local object aux.min = dmin % 60; // local object return aux; } 15