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 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 & 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> by_units(const map & courses,
const map> & enrollments ) {
map> 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 overlap(const set & numbers1, const list & numbers2) {
list 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];