Topics Runtime Error?

1) What is the best way to store a group of items? Containers 2) How can we step through all the items? & 3) What classes store items?

Ch 4

03/02/12 CMPT 212 Slides #8 © Dr. B. Fraser 1 03/02/12 2

Generic Containers QList

$ Generic Containers $ QList

  Templates: work with any (one) type of data. Declare to hold a specific type: QList studentNumbers; QList lapTimes; QList order;  Add elements using a number of methods: lapTimes. (104.3); $ Benefit of generic containers lapTimes. (102.0);  Manage dynamic memory management:  Check size: based on # items. studentNumbers.push_back(123456789); Q_ASSERT(lapTimes. == 2);  Access elements:  Provide safe access:.. cout << lapTimes ; (Arrays provide no bounds checking) cout << studentNumbers[42];

03/02/12 3 03/02/12 http://developer.qt.nokia.com/doc/qt-4.8/qlist.html 4 QList example int main(int argc, char *argv[]) QList heros; heros.push_back("Superman"); heros.append("He-Man"); heros << "She-Ra"; heros += "Dr. Evil"; Q_ASSERT(heros.size() == 4); if (heros.contains("Dr. Evil")) { Iterators cout << "Who put Dr. Evil in!?!\n"; } if (!heros.contains("Mighty Mouse")) { cout << "No mouse? What a massive omission!\n"; } cout << "\nFull list:\n"; for (int i = 0; i < heros.size(); i++) { cout << i << ": " << heros[i] << endl; } return 0; 03/02/12} 5 03/02/12 6

Direct Access Pattern

$ Direct Access $ Definition:  Use a loop to access elements "directly". The iterator pattern provides a way to access the for (int i = 0; i < heros.size(); i++) { elements of an aggregate object sequentially.. cout << heros[i] << endl; } $ Iterators work for all collections (trees, maps, list, ...) $ 3 styles: ++ std iterator, Iterator, Qt's foreach $ Iterators  Collection of Items: for (QList::iterator itr = heros.begin(); itr != heros.end(); itr++) { cout << *itr << endl; Iterator Path } 03/02/12 7 03/02/12 8 C++ std Style Iterator Java Style Iterator

C++ Standard Library Style Iterator Java Style Iterator (for Qt in C++) Define: Define & Init: Start: pizzas.begin() End: !itr.hasNext() // Setup the list... End: pizzas.end() Get & Advance: Pizza lunch = Advance: QList pizzas; pizzas.push_back(Pizza("Cheese")); Get element: *itr or itr->method() // Setup the list... // ... and more... QList pizzas; pizzas.push_back(Pizza("Cheese")); // Use a C++ Standard Library style iterator // ... and more... // to output the list. // Use a Java style iterator to output the list. for (QList::iterator itr = pizzas.begin(); QListIterator itr(pizzas); itr != pizzas.end(); while(itr.hasNext()) { itr++) Pizza p = itr.next(); { cout << p.getName() >> endl; cout << itr->getName() << endl; } } 03/02/12 9 03/02/12 10

Qt's For Each

Qt's foreach loop Iterator is.. Implemented at compile time by the Meta Object Compiler (MOC) // Setup the list... QList pizzas; pizzas.push_back(Pizza("Cheese")); Must be a const & // ... and more... because cannot QStringList and QMap foreach (const Pizza &p, pizzas) { cout << p.getName() << endl; } This actually makes a foreach (Pizza p, pizzas) { cout << p.getName() << endl; (not a reference) }

03/02/12 11 03/02/12 12 QStringList QMap

$ QMap is an $ Special list for QStrings:  QList is quite common,  Ex: Matching student numbers (key) to names (value). so made a custom class: QStringList  #include  Need #include // Create map from int to QString  Adds other operations: QMap students;

$ // Populate with data to change a QString into a QStringList students[200012345] = "Dr. Evil"; $ to merge a QStringList into a QString students[100110101] = "Ms. Binary"; students[999999998] = "Mr. Achiever";  Example: Q_ASSERT(students.size() == 3); QString str = "one, two, three"; // Mwahahahah Q_ASSERT(students[100110101] == "Ms. Binary"); Q_ASSERT(students.contains(999999998) == true); QStringList lst = str.split(", "); // Has 3 elements Q_ASSERT(students.contains(1) == false); QString together = lst.join(" ---> "); // One string. // Change the value at a key. Q_ASSERT(together == "one ---> two ---> three"); students[999999998] = "I. R. Best"; 03/02/12 13 03/02/12 14

Checking items QMap and Iterators $ Data is stored.. $ Be careful using [] with QMap // Java style iterator  // Create & populate map: Use daMap.contains(key) to.. QMap numbers; QMapIterator itr1(numbers);  Using [] to check the value at a key will.. numbers["Zero"] = 0; while (itr1.hasNext()) { numbers["One"] = 1; itr1.next(); numbers["Two"] = 2; cout << itr1.key() << ": " << itr1.value() << endl; numbers["Three"] = 3; } // Ends up creating item at index 0! // C++ STD style iterator if (students[0] != "Hamlet") QMap::const_iterator itr2 cout << "Alas, I knew him well" << endl; = numbers.constBegin(); while (itr2 != numbers.constEnd()) { cout << itr2.key() << ": " << itr2.value() << endl; // Checks for item, does not create it! ++itr2; if (students.contains(0) && students[0] != "Romeo") } cout << "Where for ought thou?" << endl; // foreach iterator: // Accessing just the values, not the keys. foreach (int value, numbers) { cout << value << endl; } 03/02/12 15 03/02/12 16 QMap Details Summary

$ Some details on challenges with QMap: $ Generic containers use templates to store any one  key type must work with.. Classes can overload < (ex: QString) type of value.  Value must be assignable (or won't compile): $ QList used to store a series of elements. $ default constructor $ Iterators abstract the notion of iteration into a class. $ copy constructor  There are 3 types of iterators supported by Qt. $ assignment operator $ QStringList useful for working with strings.  Work-around is to use a pointer. $ QMap stores (key, value) pairs.  Ex: If Pizza is not assignable, will get error with: QMap so use:..

03/02/12 17 03/02/12 18