440 likes | 831 Views
C++ for Java Programmers. Lecture 12. Yesterday. waaay back last lectuer we discussed: What is Inheritance? Base Class Access Control Protected Members Inheriting Multiple base classes Constructors & Destructors in Inheritance Different types of Access A word on Style.
E N D
C++ for Java Programmers Lecture 12
Yesterday • waaay back last lectuer we discussed: • What is Inheritance? • Base Class Access Control • Protected Members • Inheriting Multiple base classes • Constructors & Destructors in Inheritance • Different types of Access • A word on Style
One Hour Before I can go home! • Until then I’ll be talking about: • Template Functions • Template Classes • The Standard Template Library • String Class • Documentation • Coursework2
Standard Template Library • STL was one of the major aims during standardisation • It gives us many general purpose classes and functions • Implements popular algorithms and data structures • Because they are templates, the classes and functions can be used with any data type – huge flexibility.
Templates • Pretty contemporary feature. • Supported by all modern C++ compilers. • Can be used to create generic functions and classes: • take the type of data they are acting on as a parameter • We can have one function or class that works with several types of data • No need to recode specific versions for each data type
Function Templates • If functions are identical apart from the type of data they are acting on you should have a template. • A bubble-sort for example is identical whether you are using integers or floats. • So we could create a generic function that contains an algorithm but is independent of any data. • Essentially we are making functions that can overload themselves.
So how do I write one? template <class type> ret-type func-name(parameters) { //body of the code } • The class type is just a placeholder • It can represent anything – an int, float, char, etc. • It can also represent a user defined type, a class, anything. A placeholder for the type of data we will use Function names and return types keyword Takes in a list of function parameters just like a normal function.
OUTPUT: first is now 7 second is now 5 OUTPUT: first is now 7.77 second is now 5.55 OUTPUT: first is now J second is now G I still don’t get it… template <class X> void swap(X &a, X &b) { X temp; temp = a; a = b; b = temp; } int main() { int first = 7; int second = 5; swap(first, second); cout << “first is now : “ << first << endl; cout << “second is now : “ << second << endl; } float first = 5.55; float second = 7.77; char first = ‘J’; char second = ‘G’;
Bubble-sorted for e’s and whizz template <class X> void bubbleSort(X *elements, int size){ X temp; for(int i=1; i<size; i++) for(j=size-1; j>=i; j--) if (elements[j-1] > elements[j]) { temp = elements[j-1]; elements[j-1] = elements[j]; elements[j] = temp; } } int main() { int intArray = {7, 3, 9, 4, 12, 2}; double doubleArray = {4.5, 7.77, 5.55, 4.123}; bubbleSort(intArray, 6); bubbleSort(doubleArray, 4); }
Added Extras • We can use more than one class type when we setup a template: template <class X, class Y> void show(X &a, Y &b) • We can overload templates just like we would any other function - The compiler will work out which template you are trying to use. • We can also send normal parameters – not just the types we specified at the start of the template declaration. • You can also create specialisations of templates that have slightly different code than your general version, for specific types.
Class Templates • Everything we’ve done for functions above we can also apply to class structures. • Hence using the template keyword we can create generic classes too. template <class type> class className { //header for the class } • To create a specific instance of this class use the form: className <type> objectName;
Templates = Confusing Code • We also have to mention that we are in a class template when we are writing the methods for that class. • Be careful because this can make your code start to look really confused: • Method Syntax: template <class type>ret-Type className::func-name(parameters); { //body of the function } same as a normal Member function
Example Template Class template <class X, class Y> class myClass X first; Y second; public: myClass(X a, Y b) { first = a; second = b; } void show(); }; template <class X, class Y> void myClass::show() { cout << “The first value is : “ << first << endl; cout << “The second value is : “ << second << endl; }
Example Template Class int main() { myClass<int, double> object1(10, 0.23); myClass<char, char*> object2(‘J’, “Goulding”); object1.show(); cout << endl; object2.show(); } OUTPUT: The first value is 10 The second value is 0.23 The first value is J The second value is Goulding
The Power of Templates • The template<> construct can be incredibly useful. • You can create frameworks that you can apply and reapply to a whole range of programming situations. • Once debugged they are a reliable, solid software component. You can re-use them and they’re guaranteed to work.
Back to the STL • All this template syntax can seem quite intimidating. • However once you get used to them, templates are relatively simple. • They are employed in the Standard Template library to offer you off-the-shelf solutions to a variety of programming problems. • Hence the whole point of them is to try and make your life easier
3 Different Section • At the core of the STL are three conceptual items, that allow us to use such things as: • vectors • maps • lists • strings • These are the foundations of everything in the STL: containers algorithms iterators
Types of Containers • Containers are objects that hold other objects. • There are three types of container: • Sequence containers • Associative Containers • Adapted Containers • Sequence Containers – essentially linear lists : vector class list class deque class string class essentially just a dynamic array a linear linked list a double ended queue A character array – null terminated string
Associative Containers • Associative Containers – allow efficient retrieval of values based on keys. • Examples: • Every container class defines its own functions that can be applied to itself. However there are also gneral algorithms… map class multiset class provides access to values with unique keys – thus it sores a key/value pair. optimise for fast associative lookup.
Algorithms • The STL library provides a collection of generic algorithms <algo.h> which can be applied to a variety of different data structures. • STL comes with more than 70 algorithms, ranging from very simple to the extremely complex. • Most STL algorithms operate on a sequence of elements, and the algorithms access data via the use of iterators. • An example is the algorithm forcount(). count(i.begin(), i.end(), 2, n);. This counts the number of occurrences of element 2 in the vector, putting the result in n.
Iterators • An iterator is a kind of generalised pointer that may be used to traverse the elements of a container class. • At any point in time an iterator is positioned at exactly one place in a collection, and will remain there until moved. • There are five main classes of iterators: • input • output • forward • bidirectional • random access most powerful iterator – supported by vector and deque classes
Using the STL • Internally, the way the STL works and interacts is very sophisticated. • ...but you don’t need to. You just the simple interface functions. • Just decide on the type of container is best suited to the situation, create it and then use its functions. • We will be considering vectors, lists, maps and strings on this course.
Strings • Up to now we’ve been doing it the hard way. • We know C++ does not have built in support for strings. • However standard C++ can handle strings in 2 ways • The first we’ve looked at in detail – Null Terminated Strings (often called C-Strings) which are complicated but good for the soul. • But the STL also provides us with a string class too.
The String Classes This is a more generalised template class from which string is derived. basic_string string wstring This is the primary class utilised. It supports 8-bit char strings. similar class but wstring supports wide-character strings.
Are these Classes Necessary? • We’ve all become masters of the null-terminated string! Why do we need a string class? • The reason is to do with what we’ve considered in the last few lectures – operator overloading. • The basic operators such as =,+,- and so on cannot be overloaded to be able to handle null-terminated strings. For example, consider the following code: char str1[50], str2[50], str3[50] str1 = “Gordon”; //can’t do str2 = “the Gopher”; //can’t do str1 = str1 + str2; //error
Reasons for Strings • Having to use strcpy and not being able to use operators can make even rudimentary string operation clumsy. • So a String class was grudgingly implemented into the STL. • This allows strings to be used as fully integrated types, with overloaded operators and simple methods. • However Strings also add a safety net to your coding.
Part of the STL • As we discussed before STL has containers, algorithms and iterators. • the String class is a container. To include the string classes just include the <string> library at the top of your code. • 3 constructors: string(); string(const char *str); string(const string &str); Note that the string class is all in lowercase Takes in a null-terminated string Takes in another string object as a parameter all lowercase
Now we can use: = Assignment + Concatenation += Concatenation Assignment == Equality != Inequality < Less than <= Less than or equal > Greater than >= Greater than or equal [ ] Subscripting << Output >> Input Now we don’t need functions such as strcpy() and strcat() Just overloading the [ ] operators so they can be used as indexing.
Inside the Template Library • Remember the trouble we noted with overloaded methods – the object from the class had to come first. • We would potentially have the same problem here. • It is solved in the same way - <string> contains non-member functions to overload the operators that are then set as friends in the class. • This means we can have: string + string string + C-string C-string + string
Scooby-Doo Example 3 Different ways of setting up an object of the string class string str1 = “Shaggy”; string str2(“Doo”); string str3(str2); str2 = “Scooby” + str3; str3 = “Scrappy” + str3; cout << str1 << “ says... *it wasn’t me…* ”; if (str3<str2) cout << str3 << “comes before “ << str2; else cout << str2 << “comes before “ << str3; cout << “Type in your name:”; cin >> str1; cout << str1 << “ would have got away with it ” << “if it wasn’t for you pesky kids”; concatenation comparison inputting
How long is a string? • The most important point of this however is that at no point do you define how long your string will be. • string objects automatically size and re-size themselves. • Hence it is not possible to overrun the end of as string like you can with null terminated strings. • Immediately alarm bells should be ringing and “DMA” appearing in neon lights in your head. • DMA is being used - its just hidden, like in Java.
Strings are Containers • The string class is a container, and so it supports all of the common container functions. • They also support all of the STL’siterator and algorithm functions. • The most commonly used function is the .size() method: for (i=0; i<str.size(); i++) cout << str[i]; cout << endl;
Dedicated Methods • String is a class, and so naturally, as well as all these overloaded operators, it has all sorts of methods too. • Many duplicate what the operators do, but with added functionality. • For example the assign method and = do almost identical things. However the method version can assign just a section of a string. E.G.: string str1 = “Hello World”; string str2; str2.assign(str1, 6, 5); CONTAINS: World
Substrings • Another capability provided by the class string is substr, which returns the substring of a string. • The substring is specified as a starting position and a length as arguments to substr. string date = “March 7, 1994”; string year = date.substr(9, 4); cout << “Year is “ << Year << endl; • If you go over the strings limits these values are just set to the max possible.
Appending • Of course we would use + to concatenate a string. • However this is just a specific use of the more general append method: string &append(const string &str, start, num); • The start and num parameters indicate what parts of str should be appended. For example: string str1(“Scooby DOO”); string str2(“Scrappy”); str2.append(str1, 7, 3); cout << str2; OUTPUT: Scrappy DOO
Inserting • Insert: string &insert(position, str, start, num); • The start and num parameters indicate what parts of str should be taken, to insert at place position in the string. string str1(“Scooby DOO”); string str2(“Scrappy”); str2.insert(2, str1, 7, 3); cout << str2; OUTPUT: ScDOOrappy
Replacing & Erasing • The replace method is identical to insert except it overwrites the characters that were already there. string str1(“Scooby DOO”); string str2(“Scrappy”); str2.insert(2, str1, 7, 3); cout << str2; • Erase() is the method you would use to remove characters from your string. OUTPUT: ScDOOpy
Comparing • To compare the entire contents of a string lexigraphically, we would use the > operator that we looked at earlier. • However, as with most of these methods, compare is useful if we only want to look at portions of these strings: int compare(start, num, str); • So the first num characters from position start in str, will be compared with the invoking string project.
Searching… • The string class also provides the ability to find a substring within a string – the find() method. • Find accepts two arguments - the search string and the starting position for the search string scooby = “Wilma’s lost her glasses…again”; int i = scooby.find(“her”, 0); cout << “i is “ << i << endl; • The member function returns an integer of the position of the first match. rfind() does the same job but works backwards. start point
Getting at the C-String… • string objects can be incredibly but what if you’re a purist and want a null-terminated string. (E.g. when opening a file). • Its easy to do. Just use…. const char *c_str() const; • This returns a point to the null terminated character array within the string object. Take care with it because it can easily change: • Eg: fstream fin( fileName.c_str() );
Documentation • Essentially your documentation should cover standard software readme's, covering: * HEADING * PLATFORM * WHAT THE CODE WAS WRITTEN IN * PROGRAM FUNCTIONALITY * ANY KNOWN WEAKNESSES (very important) * POSSIBLE FUTURE FUNCTIONALITY A Final section should also be included: * HOW YOUR PROGRAM IS STRUCTURED
Coursework 2 • Will be online soon - the deadline for it however is ages off – 5pm Friday 17th May • It will require: • More OO than you can shake a stick at • Inheritance • Operator Overloading • DMA • File I/O • You WILL be good at C++ after this course
Exercise of the day • Write a program that reads a text from standard input and prints a list of words of length less than 4 and their frequency in the text. • Suppose words consist of letters a-zA-Z only.