Announcements CSCI 4: Principles of Programming Languages Lecture 19: C++ HW8 pro tip: the HW7 solutions have a complete, correct implementation of the CPS version of bubble sort in SML. All ou need to do is encode the same logic in C++. Instructor: Dan Barow Announcements Dnamic Dispatch (ala Smalltalk) Superclass Point object Point class Template I ve decided to skip Java. ColoredPoint object ColoredPoint class Method dictionar Method dictionar Template
Call on ColoredPoint Superclass Point object Point class Template Optimize Dnamic Dispatch Superclass Point object Point vtable class Template 4 Method dictionar ColoredPoint object ColoredPoint class 1 Method dictionar Template 5 6 Method dictionar Static tpes let us do some optimization. Sacrificing runtime polmorphism-b-default also allows optimization. Staticall determine locations of and. Non-virtual method lookup determined staticall. Cop virtual methods from superclasses into method dictionar. Eliminate class object; just a virtual function table now. Optimize Dnamic Dispatch Call on ColoredPoint C++ virtual dispatch never searches as in SmallTalk! Point object Point vtable Point object Point vtable ColoredPoint object ColoredPoint vtable ColoredPoint object ColoredPoint vtable 1
Runtime polmorphism You ma have forgotten how OO polmorphism works. It s eas to forget with Smalltalk, which is dnamicall tped. In Java and especiall C++ ou need to think about this or it will bite ou. class Animal { string mname() { return "Animal"; ; What will the last line print? Animal *a = new Animal(); cout << a->mname() << endl; Human *h = new Human(); cout << h->mname() << endl; a = h; cout << a->mname() << endl; class Human : public Animal { string mname() { return "Human"; ; Runtime polmorphism You ma have forgotten how OO polmorphism works. It s eas to forget with Smalltalk, which is dnamicall tped. In Java and especiall C++ ou need to think about this or it will bite ou. class Animal { virtual string mname() { return "Animal"; ; What will the last line print? Animal *a = new Animal(); cout << a->mname() << endl; Human *h = new Human(); cout << h->mname() << endl; a = h; cout << a->mname() << endl; class Human : public Animal { virtual string mname() { return "Human"; ; Inheritance vs Subtping class Pirate : public Person { Pirate(string name); virtual void sahello(); Recall that inheritance and subtping are not the same. Eample: implement a stack using a dequeue. Inheritance of the form: class <subclass> : <superclass> is mere inheritance; the C++ compiler will not treat <subclass> as a subtpe of <superclass> Inheritance of the form: class <subclass> : public <superclass> is inheritance with subtping; the compiler will treat <subclass> as an instance of <superclass> when needed. Initializer Lists Pirate::Pirate(name) : Person(name) { In C++, the base class constructor is called automaticall for ou for no-argument constructors. When calling a superclass constructor with an argument from a subclass, ou must use initializer list snta. This is different from Java. You can (and should) also use the initializer list to call constructors for instance variables if the need initialization. Initializer lists onl work for instance variables that have constructors; primitives do not have constructors. For primitives, initialize the old-fashioned wa (in constructor bod).
Manual Memor Management In C++, ou need to think eplicitl about allocation and deallocation, just as ou do in C. While ou can use malloc and free in C++, ou should generall favor new and delete instead. new does more than malloc: it also calls the class constructor. delete does more than free: it also calls the class destructor. class String { private: char *s; int size; String(char *); ~String(); ; String::String(char *c) { size = strlen(c); s = new char[size+1]; strcp(s,c); Destructors constructor destructor String::~String() { delete []s; Automatic vs. Heap Allocation Tpe Inference! int main() { Pirate dan = Pirate( Dan ); dan.sahello(); allocated on the stack! access member using. Pirate *karen = new Pirate( Karen ); karen->sahello(); allocated on the heap access member using -> (remember, this is sntactic sugar) C++ has a restricted form of tpe inference. int main() { auto dan = Pirate( Dan ); dan.sahello(); auto karen = new Pirate( Karen ); karen->sahello(); auto makes life wonderful. Use it unless ou are confused about inferred tpes (in which case, write the tpe manuall)
Lambda epressions C++ has lambda epressions. The are a tad more verbose than in SML. Three main components. 1. Parameter list. Function bod.capture list 1 [ ]( ){ Lambda epressions 1 [ ]( ){ Let s rewrite this SML lambda epression in C++: fn (: int) => + 1 []( int ){ return + 1; ; Lambda epressions 1 [ ]( ){ Lambda epressions 1 [ ]( ){ Let s rewrite this SML lambda epression in C++: val = fn (: int) => + Let s rewrite this SML lambda epression in C++: val = fn (: int) => + int = ; [ ]( int ){ return + ; ; Captures b value (copies value of ) int = ; [& ]( int ){ return + ; ; Captures b reference (refers to )
Lambda epressions Lambda subtleties What is the tpe of a lambda epression? [&](int ){return + ;; This one takes an int and returns and int std::function<int(int)> More generall.. std::function<t(u 1,,U n )> Capture of closed-over lambda parameters is onl necessar for variables with automatic storage duration. (demo) Templates C++ lets ou program genericall just like Java or SML. Snta is a little different. Mechanism is ver different. class Bo { int ; Bo b = new Bo(); b-> = ; Templates No restriction on template parameter like Java (int vs Integer) Works b generating specialized code (literall, a new class) at compile-time for each parameter tpe used. template <tpename T> class Bo { T ; Bo<double> b = new Bo<double>(); b-> =.;
Templated Lambdas You can even template lambda epressions. Here s a generic identit function. template <tpename T> auto Identit = [](T ){return ;; Call it like: Identit<string>( hello ); Tpedef d Templates You can even tpedef templated tpes. Unfortunatel, the tpedef mechanism does not understand template parameters, which means that ou have to fi the template parameter if ou use it. C++0 introduced a generalization of tpedef to address this called using. std::function<bool(t,t)> Won t work; doesn t understand T: template <tpename T> tpedef Comparison std::function<bool(t,t)>; Will work: template <tpename T> using Comparison = std::function<bool(t,t)>; Net class Scala wrap-up Logic programming