In lecture we defined a Bag ADT using a dynamic array as its underlying data structure:
size() memeber function simply returns count.
The implementation of print prints the values to
the stream. It makes it easier to test bag functions.
The add and remove_any implementations are only a few
lines each:
If we use the default implementation for operator=:
b and b3 will both be pointing at the same array.
This will cause things to go wrong. Continue the example and
explain what unexpected things happen. Draw pictures.
b3.add("eggs");
b.add("flour");
cout << b3.remove_any();
// Expected output: eggs
// Actual output: flour
The actual output happens because the addition of ``flour'' uses b's
count, which is unchanged at 2, and so overwrites the ``eggs.''
Alternatively, one could simply print out b3:
b3.add("eggs");
b.add("flour");
b3.print(cout);
// Expected output: ham, carrots, eggs
// Actual output: ham, carrots, flour
Another, less satisfying solution is to haveb3in a nested scope, and close that scope and then printb. This would (probably) crash, because we would be accessing an array of destructed strings.
The following attempts from actual quizzes won't work:
cout << b.remove_any(); // expected output: carrots cout << b3.remove_any(); // expected output: carrots
Both will print"carrots"as expected. The reason why is that theremove_anyfunction does not change the array, so there is no way to observe the fact that the array is shared.
b3.add("ginger");
b3.add("apples");
b3.add("ice cream");
This will add three new items tob3which will cause the old array to be deleted and a new array allocated forb3. Nowbis pointing to a deleted array. But the code above doesn't do anything withb. This would get full credit if we then printedb, which would probably cause the program to crash.
b3.add("pop");
b3.add("sugar");
cout << b3.remove_any();
b3.print(cout); // expected output: ham, carrots, pop
Again nothing strange will be observed. We will add the two new items to the array, and thenb3's count will be reduced to 3, but still it will look fine. And even if we printedbat this point, it would still be fine.
b.add("onions");
b.add("cookies");
cout << b3.remove_any(); // expected output: carrots
Remember thatb3's count is unaffected byb's additions. Sob3'sremove_anystill returns the expected ``carrots.'' Furthermore, even if we printedbat this point, nothing strange would be observed, becauseremove_anydoes not change the array.
cout << b3.remove_any(); // expected output: carrots b3.print(cout); // expected output: ham
An exercise for the reader: why does this not flush out the bug?
Why is even printing b at this point useless?
b3.add("chicken");
(void) b3.remove_any();
(void) b3.remove_any();
cout << b.remove_any(); // expected output: carrots
Another exercise. Remember that remove_any doesn't change
the array.