CSE390C Key to Final, Winter 2026 handout #9 1. Statement Output ------------------------------------------------------------ var1->f1(); foo 1 var2->f1(); bar 1 var3->f1(); mumble 1 var4->f1(); mumble 1 var5->f1(); foo 1 var1->f2(); foo 2 var2->f2(); foo 2 var3->f2(); foo 2 var4->f2(); mumble 2 var5->f2(); baz 2 var1->f3(); foo 3 var2->f3(); foo 3 var3->f3(); foo 3 var4->f3(); foo 3 var5->f3(); baz 3 2. One possible solution appears below. class history_string { public: history_string(const string & text) { history.push_back(new string(text)); } history_string(const history_string & rhs) { for (string * p : rhs.history) { history.push_back(new string(*p)); } } ~history_string() { for (string * p : history) { delete p; } } history_string & operator=(const history_string & rhs) { if (this != &rhs) { for (string * p : history) { delete p; } history.clear(); for (string * p : rhs.history) { history.push_back(new string(*p)); } } return *this; } const string & get_string() const { return *(history.back()); } void reset(const string & s) { history.push_back(new string(s)); } bool can_undo() const { return history.size() > 1; } void undo() { string * p = history.back(); history.pop_back(); delete p; } private: vector<string *> history; }; 3. One possible solution appears below. class asset { public: virtual double basis() const = 0; virtual ~asset() { } double profit_or_loss(double value) const { return value - basis(); } }; class stock : public asset { public: stock(const string & s) : symbol(s) { // nothing more to do } void buy(int number, double per) { cost += number * per; shares += number; } double basis() const { return cost; } private: string symbol; int shares; double cost; }; 4. One possible solution appears below. int longest_sorted(const vector<int> & data) { int best = 0; int i = 0; int count = 1; for (int i = 0; i + 1 < data.size(); i++) { if (data[i] <= data[i + 1]) { count++; } else { count = 1; } if (count > best) { best = count; } } return best; } 5. One possible solution appears below. map<int, set<string>> by_units(const map<string, int> & courses, const map<string, set<string>> & enrollments ) { map<int, set<string>> result; for (const auto & entry : enrollments) { int sum = 0; for (const string & course : entry.second) { sum += courses.find(course)->second; } result[sum].insert(entry.first); } return result; } 6. One possible solution appears below. list<int> overlap(const set<int> & numbers1, const list<int> & numbers2) { list<int> result; for (int n : numbers1) { int num = count(numbers2.begin(), numbers2.end(), n); for (int i = 0; i < num; i++) { result.push_front(n); } } return result; } 7. The question was to give examples of when it is appropriate to write code like this: data & foo(...) { ... return x; } There are several cases where we would know that a variable exists that can be accessed by the client. For example: * x is an instance variable * x is a reference parameter to foo (as in istream & out) * x is an alias to a heap-allocated variable we have a pointer to int & x = *p; * x is an alias to an element of a structure passed as a parameter: string & x = v[i];
Stuart Reges
Last modified: Fri Mar 20 16:31:31 PDT 2026