250 likes | 431 Views
More C++. CSE399 Feb 13, 2007. Before we get started(1). Project proposals due ~3 weeks 1, 2, or 3 people (suggested: 2) Project complexity proportional to group size Pick something interesting Simple Game: SDL (man -k SDL) / OpenGL Interpreter for some (reasonably simple) language
E N D
More C++ CSE399 Feb 13, 2007
Before we get started(1).. • Project proposals due ~3 weeks • 1, 2, or 3 people (suggested: 2) • Project complexity proportional to group size • Pick something interesting • Simple Game: SDL (man -k SDL) / OpenGL • Interpreter for some (reasonably simple) language • A simple command shell with a couple cool features • An application of whatever field of CS you like
Doing the project • Projects will be demoed to me at end of semester • April 21,23,25 during the 12-1 timeslot • Platform of your choice, as long as can be demoed at school (lab or laptop) • Coding in C++ • Be ready to explain what C++ features were helpful
Before we get started (2). • Homework 2: Solutions online • Homework 3: Assigned last week, due next • Should free() copy of key in remove • Hashtable info on website
Into C++ • Last week: C++ class basics • Highlights: • Need virtual keyword for dynamic dispatch • public:, private: rather than on each member • Semi-colon at end of class declaration • Note: use g++ to compile C++ programs
Destructors • Constructors: Named same as class, called when new’ed • Destructors: Named same as class, but with a ~, called when delete’ed class Foo{ public: Foo() {….} ~Foo() {….} }
Pass by reference • C only passes by value • void foo(int *x) passes a pointer by value • In C++, can pass by reference: void swap (int &x, int &y) { int temp = x; x = y; y = temp; } ….. swap (a, b);
Templated Functions • Functions may be parameterized over types or values • Templates must be instantiated to use • Values must be constant • Separate code for each set of template parameters • Type checking done after instantiation
Template Example template<class T> void swap(T &x, T &y){ T temp = x; x = y; y = temp; } int a = 3, b = 4; double c = 3.14, d = 42; swap<int>(a, b); swap<double>(c, d);
Template Example 2 template <class T1, class T2, class T3 T1 (*f) (T2), T2 (*g) (T3)> T1 composition (T3 x) { return f(g(x)); } …. int (*h)(int) = composition<int, int, int, inc,mulBy3>;
Template miscellanea • Compiler can sometimes infer type arguments: int a, b; swap(a,b); /* compiler knows swap<int>(a,b) */ • Compiler can optimize each template instantiation separately
Templated Classes • C: void * = generic data structure struct llnode{ void * data; struct llnode * next; } • Ugly because… • Not type safe • Always need to allocate memory- even for int lists etc
Templated Classes • In C++, use templated classes: template<class T> class LLNode{ private: T data; LLNode<T> * next; public: T getData() {return data;} …. } • Note: LLNode must be instantiated with T for next
Template Specialization • Can specify a different definition for a specific set of parameters: template<class T> class X{ …. }; template<> class X<int> { …. }; • Note: This is not inheritance.
A benefit of the way templates work • Body only needs to be valid for instantiated types: template<class KeyT, class DataT> BST{ …. void add(KeyT k, DataT d){ BSTNode<KeyT, DataT> * curr = root; …. if(curr->key < k) { …. • < not defined on all types- OK as long as you don’t try to use for KeyT (in a few slides, we see how to define < for other types)
A downside of how templates work • The compiler must instantiate each template • Definition must be visible • Can’t simply link against it • Actual template code is put in .h file • Compiler designed to make sure linker is happy with this arrangement • Seems offensive to C programmers
Factorial.. in templates? template<int N> int factorial(){ return N * factorial<N-1>(); } template<> int factorial<0>() { return 1; } …. int a = factorial<6>(); • With -O3, compiles to a = 720;
Overloaded functions • Same name, different arg lists: void foo(int x) void foo(double d) • Legal in C++ (not C) • Compiler “mangles” name to make linker happy _Z3fooi, _Z3food • extern “C”: don’t mangle- for linking with C
Overloaded Operators • Most operators can be overloaded too • All but . .* ?: :: • Can’t overload for only built-in types (I.e. overloaded operator must involve a user defined type, such as a class) • Cannot make new operators nor change arity, precedence, or associativity • Use the operator keyword: class Foo{ int operator+ (int x) {….} }; • Question: What is the other argument?
Benefits of operator overloading • Remember this: template<class KeyT, class DataT> BST{ …. void add(KeyT k, DataT d){ BSTNode<KeyT, DataT> * curr = root; …. if(curr->key < k) { …. • Any type that overloads operator< can be used as the key
Downsides to operator overloading • Overloaded operators don’t short circuit • Badly overloaded operators can confuse a programmer • Need to be careful of self-assignment for operator= • Naïve: free old, assign new • lhs same as rhs: reads free()ed mem
Namespaces • Restrict visibility of a name namespace foo{ int x; void bar() { …} } • Access members with scope resolution operator foo::bar() or foo::x • Global namespace: nothing on lhs of :: ::somevariable • The using keyword opens a namespace: • using namespace foo;
IO C++ style • printf/fgets still work, but… • C++ uses iostreams, which overload << and >> #include <iostream> //declares std::cout, std::endl using namespace std; // can skip std:: int main(void) { cout << "Hello World" << endl; return 0; }
Input: cin • Input can be read with cin and >> string s; // C++ introduces a string class int x; cout << “Type a string ” << endl; cin >> s; cout << “Type a number ” <<endl; cin >> x; //Non-numeric input left for next read
Overloading << and >> • Classes can specify serialization behavior with << and >> class Foo{ … friend istream& operator>>(istream&, Foo&); friend ostream& operator<<(ostream&, const Foo&); }; ostream& operator<<(ostream& out, const Foo& f) { out << f.something; return out; }