CS120 - Day 10: C++ Basics, Templates, STL; pair programming -------------------------------------------------------------- Object Oriented Programming returns with C++!! Everything you learned in C can be done in a C++ program. Use www.cplusplus.com to look up class libraries and functions! Compiling: - name files .cc or .cpp - use g++ (not gcc) [-pedantic -Wall -Wextra -std=c++98 -O] - continue to use makefiles! Program organization: - functions and classes used to organize code - functions can exist without classes (like in C) - executable programs must have "main" function, but no class - function prototypes appear before function, just header info - prototypes important for compiler error and type checking - prototype required if function use precedes definition - #include "myheader.h" where myheader.h has prototypes - don't put "using" in header files (see below) ****************** SAMPLE FILE: start.cpp ********************** Basics to note: - preprocessing: library names, namespaces - data types & casting - I/O - stream processing - reference parameters - string objects Pre-Processing ---------------------------------------- Many C libraries have different names when used in C++ programs - built-in math functions #include // is old name - others: etc. - C++ libraries: - eg: #include // C++ header file for i/o stuff Namespaces The libraries are defined in namespaces, and we need to clarify where objects exist (name scope) even if we #include the relevant library. Standard namespace is where things like cout, cin, etc. reside. There are three ways to do this: 1) Qualify things with namespace:: std::cout << "hi there" << std::endl; :: is a scope operator in C++ to specify where names are defined (we will see it again when we write classes) 2) Put individual using declarations at the start of your file: using std::cout; using std::cin; using std::endl; using std::string; 3) Claim you are using an entire namespace at the start: using namespace std; - advantages & disadvantages of "using namespace std;" - don't put "using" declarations in header files Data types (added to C) -------------------------------- - bool (true, false) - size_t (used for the sizes of types) - container(string, vector, etc)::size_type - cast operators - newer syntax: static_cast(value) I/O------------------------------------------------------ std::cin >> thing1 >> thing2; // cin is standard input stream std::cout << thing1 << thing2; // cout is standard output stream std::cout << '\n' << std::endl; // newline, newline and flushes buffer std::cin.get(ch); // read one character // or with appropriate using declarations: cin >> thing1 >> thing2; // cin is standard input stream cout << thing1 << thing2; // cout is standard output stream cout << '\n' << endl; // newline, newline and flushes buffer cin.get(ch); // read one character - will read into any primitive data type - uses all forms of whitespace to tokenize - invalid input (wrong data type) puts stream in error condition - << and >> are binary operators, result is modified stream, allows chaining - using cin as loop control: value is true in boolean expr if stream is in good state, false otherwise eg: while (cin >> n) process(n); while (cin.get(ch)) process(ch); *** flush output: std::cout << std::flush; - automatically flushed with \n or endl, or read statement, or full REFERENCES & parameters ---------------------------------- - simple data types are passed by value - pointers (like in C) can be used to pass by reference - NEW: can use & to reference variable - passed by reference - think of & as 'alias' for a parameter - in method call just use variable name (not address of) EXAMPLE: int main() { int a = 10, b = 10, c = 10; function(a, &b, c); cout << a << ' ' << b << ' ' << c << std::endl; // 10, 15, 20 } void function(int value, int * pointer, int & alias) { value = value + 1; // no effect on calling argument *pointer = *pointer + 5; // changes calling argument alias = alias + 10; // changes calling argument } STRING class ------------------------------------------------ #include // not , these are different - string is class name, not reserved word - these are the full objects, not references to objects! - constructors - called with function notation, not new std::string s1("hello"); std::string s2(3, 'x'); // makes "xxx" std::string s3 = " world"; // calls copy constructor std::string s4; // empty string "" (not null variable!) // implicitly calls default constructor std::string s5(s2); // copy constructor - conversions - no constructor for int or char conversions - can assign character: s1 = 'h'; - operations = for assignment of literals >> input from stream - stops at whitespace! << output to stream getline(is, str) // read to end of line from stream is, store in str s1 = s2; deep copy assignment or s1.assign(s2) or s1.assign(s2, start, howmany) + concatenation += concat & assign or s1.append(s2) == s1 += s2 relational operators overloaded (great language feature!): < > <= >= - representation & statistics string object is not a pointer, not null terminated [] used to get individual characters, no range checking, 0..length-1 at(int) to get individual chatacters with range checking - throws out_of_range exception s1.size() = s1.length() == number of characters s1.capacity() // how many it can hold s1.max_size() // max for all strings s1.empty() // bool s1.reserve(s1.length() + 5); //changes capacity & size s1.substr(where, howmany); s1.compare(s2); s1.c_str(); // get c-style string (null terminated character array) - String comparisons int f = s1.compare(s2); (- if s1s2) overloaded substring versions of compare operators: == != < > <= >= because of operator overloading in C++ Standard Template Library (STL) in C++ ----------------------------- Provides basic containers (data structures) and algorithms to make our programming jobs much easier! We'll use, then learn how to write. Sequence Containers: , (String is a vector of chars) Common operations for sequence containters: - front() reference to 1st element - back() reference to last element - push_back(val) returns void - pop_back() returns void, use back() to get value before pop Requirements of base data type: copy constructor, = , == , <, default constructor for initialization - template concepts - define a class or function that can be used with multiple data types - the actual data type becomes in some sense a parameter - iterator concepts - moves through a collection, one item at a time - in the STL they are pointers >>>>>> EXAMPLE: containers.cpp <<<<<<<<<< Vectors ------------------------------------------------------------- - smart array - inserts and deletes at back are very efficient - insert or delete in middle are slow bc have to shift elements - access elements with [] notation, no range error checking - at(sub) is like [] with range checking - when full, will resize to add more memory and copy to new memory - most implementations double the size for efficiency - can use resize to control - good random access (subscripting) performance - supports random access iterators - supports all algorithms - declare: vector v; // empty vector vector::const_iterator cvi; // constant iterator vector::iterator vi; // mutable iterator vector::size_type vsize; const int SIZE=5; int a[SIZE] = {2, 3, 4, 5, 6}; vector v(a, a+SIZE); // constructor takes iterator (pointer/address of array) // start at a and stop before a+SIZE // initializes v to the contents of array a vector v(10); // vector size 10 // elements initialized to 0 vector v2(10, 5); // vector size 10, init to 5 if (v.empty()) v.assign(10, 2); // size 10, init to 2 v.assign(a, &a[SIZE]); v.assign(v2.begin(), v2.end()); v.resize(25, 2); // add elements init to 2, size 25 v.reserve(25); // capacity 25, no init - insert(iter pos, value) // insert before pos - insert(iter pos, startiteratorposition, enditeratorposition + 1) - erase(iter pos) // remove at pos, return iterator to next element - erase(iter start pos, iter end position + 1) - similar constructors & functions for the other sequence containers!! Iterators ----------------------------------------------------------- - const and non-const versions - works by using pointers!! - begin() - returns pointer to first element - end() - returns pointer after last element - can do addition on iterators to advance vector dv; vector::iterator di = dv.begin(); di++; di = di + 3; di = dv.erase(di); delete the item pointed to by di, make di point to next element in dv while (di != dv.end()) Lists ------------------------------------------------------------------ - doubly linked list w/pointers - efficient for insert/delete in the middle - list ops: splice, merge, front(), push_front(val), pop_front(), remove(val), unique() (must sort first), reverse() - sorting - list.sort() relies on < operator - list.sort(cmp) uses predicate comparator function cmp (pointer to function?!) bool compare(const Card & x, const Card & y) { return x.face < y.face; } sort(hand.begin(), hand.end(), compare);