Question1:
A black box test of a class is a program that tests the correctness of the class’s member functions without directly examining the private members of the class. You can imagine that the private members are inside an opaque black box where they cannot be seen, so all testing must occur only through activating the public member functions.
Write a black box test program for the bag class. Make sure that you test the boundary values, such as an empty bag, a bag with one item, and a full bag.
My answer:
bag1.h和bag1.cpp摘自书本。
bag1.h
// FILE: bag1.h
// CLASS PROVIDED: bag (part of the namespace main_savitch_3)
//
// TYPEDEF and MEMBER CONSTANTS for the bag class:
// typedef ____ value_type
// bag::value_type is the data type of the items in the bag. It may be any of
// the C++ built-in types (int, char, etc.), or a class with a default
// constructor, an assignment operator, and operators to
// test for equality (x == y) and non-equality (x != y).
//
// typedef ____ size_type
// bag::size_type is the data type of any variable that keeps track of how many items
// are in a bag.
//
// static const size_type CAPACITY = _____
// bag::CAPACITY is the maximum number of items that a bag can hold.
//
// CONSTRUCTOR for the bag class:
// bag( )
// Postcondition: The bag has been initialized as an empty bag.
//
// MODIFICATION MEMBER FUNCTIONS for the bag class:
// size_type erase(const value_type& target);
// Postcondition: All copies of target have been removed from the bag.
// The return value is the number of copies removed (which could be zero).
//
// bool erase_one(const value_type& target)
// Postcondition: If target was in the bag, then one copy has been removed;
// otherwise the bag is unchanged. A true return value indicates that one
// copy was removed; false indicates that nothing was removed.
//
// void insert(const value_type& entry)
// Precondition: size( ) < CAPACITY.
// Postcondition: A new copy of entry has been added to the bag.
//
// void operator +=(const bag& addend)
// Precondition: size( ) + addend.size( ) <= CAPACITY.
// Postcondition: Each item in addend has been added to this bag.
//
// CONSTANT MEMBER FUNCTIONS for the bag class:
// size_type size( ) const
// Postcondition: The return value is the total number of items in the bag.
//
// size_type count(const value_type& target) const
// Postcondition: The return value is number of times target is in the bag.
//
// NONMEMBER FUNCTIONS for the bag class:
// bag operator +(const bag& b1, const bag& b2)
// Precondition: b1.size( ) + b2.size( ) <= bag::CAPACITY.
// Postcondition: The bag returned is the union of b1 and b2.
//
// VALUE SEMANTICS for the bag class:
// Assignments and the copy constructor may be used with bag objects.
#ifndef MAIN_SAVITCH_BAG1_H
#define MAIN_SAVITCH_BAG1_H
#include <cstdlib> // Provides size_t
namespace main_savitch_3
{
class bag
{
public:
// TYPEDEFS and MEMBER CONSTANTS
typedef int value_type;
typedef std::size_t size_type;
static const size_type CAPACITY = 30;
// CONSTRUCTOR
bag( ) { used = 0; }
// MODIFICATION MEMBER FUNCTIONS
size_type erase(const value_type& target);
bool erase_one(const value_type& target);
void insert(const value_type& entry);
void operator +=(const bag& addend);
// CONSTANT MEMBER FUNCTIONS
size_type size( ) const { return used; }
size_type count(const value_type& target) const;
private:
value_type data[CAPACITY]; // The array to store items
size_type used; // How much of array is used
};
// NONMEMBER FUNCTIONS for the bag class
bag operator +(const bag& b1, const bag& b2);
}
#endif
bag1.cpp
// FILE: bag1.cpp
// CLASS IMPLEMENTED: bag (see bag1.h for documentation)
// INVARIANT for the bag class:
// 1. The number of items in the bag is in the member variable used;
// 2. For an empty bag, we do not care what is stored in any of data; for a
// non-empty bag the items in the bag are stored in data[0] through
// data[used-1], and we don't care what's in the rest of data.
#include <algorithm> // Provides copy function
#include <cassert> // Provides assert function
#include "bag1.h"
using namespace std;
namespace main_savitch_3
{
const bag::size_type bag::CAPACITY;
bag::size_type bag::erase(const value_type& target)
{
size_type index = 0;
size_type many_removed = 0;
while (index < used)
{
if (data[index] == target)
{
--used;
data[index] = data[used];
++many_removed;
}
else
++index;
}
return many_removed;
}
bool bag::erase_one(const value_type& target)
{
size_type index; // The location of target in the data array
// First, set index to the location of target in the data array,
// which could be as small as 0 or as large as used-1. If target is not
// in the array, then index will be set equal to used.
index = 0;
while ((index < used) && (data[index] != target))
++index;
if (index == used)
return false; // target isn’t in the bag, so no work to do.
// When execution reaches here, target is in the bag at data[index].
// So, reduce used by 1 and copy the last item onto data[index].
--used;
data[index] = data[used];
return true;
}
void bag::insert(const value_type& entry)
// Library facilities used: cassert
{
assert(size( ) < CAPACITY);
data[used] = entry;
++used;
}
void bag::operator +=(const bag& addend)
// Library facilities used: algorithm, cassert
{
assert(size( ) + addend.size( ) <= CAPACITY);
copy(addend.data, addend.data + addend.used, data + used);
used += addend.used;
}
bag::size_type bag::count(const value_type& target) const
{
size_type answer;
size_type i;
answer = 0;
for (i = 0; i < used; ++i)
if (target == data[i])
++answer;
return answer;
}
bag operator +(const bag& b1, const bag& b2)
// Library facilities used: cassert
{
bag answer;
assert(b1.size( ) + b2.size( ) <= bag::CAPACITY);
answer += b1;
answer += b2;
return answer;
}
}
main.cpp
#include <iostream>
#include "bag1.h"
using namespace std;
int main(){
// prepare to test
main_savitch_3::bag bag1;// 现在是空的
cout << "Declare a new bag called bag1." << endl;
cout << "Keep inserting new items into bag1 until it is full." << endl;
for(int i = 0; i < bag1.CAPACITY; i++){
bag1.insert(i);
cout << "Now there are " << bag1.size() << " item(s) in bag1." << endl;
}
cout << "Erase one item from bag1." << endl;
if(bag1.erase_one(28) == true){
cout << "Succeed to erase 28 from bag1" << endl;
} else {
cout << "Failed to erase 28 from bag1" << endl;
}
cout << "Now there are " << bag1.size() << " item(s) in bag1." << endl;
cout << "Declare bag2" << endl;
main_savitch_3::bag bag2;
cout << "Insert 2 into bag2" << endl;
bag2.insert(2);
cout << "bag2 = bag1 + bag2" << endl;
bag2 += bag1;
cout << "How many 2s in bag2?" << endl;
cout << "Here are " << bag2.count(2) << "2(s)" << endl;
cout << "Try to erase 2 from bag2." << endl;
cout << "Erase " << bag2.erase(2) << " 2(s) from bag2" << endl;
cout << "How many 2s in bag2 now?" << endl;
cout << "Here are " << bag2.count(2) << " 2(s)" << endl;
cout << "How many item(s) in bag2 now?" << endl;
cout << "Here are " << bag2.size() << "item(s) in bag2 now." << endl;
cout << "bag3 = bag1 + bag2, items exceed" << endl;
main_savitch_3::bag bag3 = bag1 + bag2;
return 0;
}
结果:
Declare a new bag called bag1.
Keep inserting new items into bag1 until it is full.
Now there are 1 item(s) in bag1.
Now there are 2 item(s) in bag1.
Now there are 3 item(s) in bag1.
Now there are 4 item(s) in bag1.
Now there are 5 item(s) in bag1.
Now there are 6 item(s) in bag1.
Now there are 7 item(s) in bag1.
Now there are 8 item(s) in bag1.
Now there are 9 item(s) in bag1.
Now there are 10 item(s) in bag1.
Now there are 11 item(s) in bag1.
Now there are 12 item(s) in bag1.
Now there are 13 item(s) in bag1.
Now there are 14 item(s) in bag1.
Now there are 15 item(s) in bag1.
Now there are 16 item(s) in bag1.
Now there are 17 item(s) in bag1.
Now there are 18 item(s) in bag1.
Now there are 19 item(s) in bag1.
Now there are 20 item(s) in bag1.
Now there are 21 item(s) in bag1.
Now there are 22 item(s) in bag1.
Now there are 23 item(s) in bag1.
Now there are 24 item(s) in bag1.
Now there are 25 item(s) in bag1.
Now there are 26 item(s) in bag1.
Now there are 27 item(s) in bag1.
Now there are 28 item(s) in bag1.
Now there are 29 item(s) in bag1.
Now there are 30 item(s) in bag1.
Erase one item from bag1.
Succeed to erase 28 from bag1
Now there are 29 item(s) in bag1.
Declare bag2
Insert 2 into bag2
bag2 = bag1 + bag2
How many 2s in bag2?
Here are 2 2(s)
Try to erase 2 from bag2.
Erase 2 2(s) from bag2
How many 2s in bag2 now?
Here are 0 2(s)
How many item(s) in bag2 now?
Here are 28item(s) in bag2 now.
bag3 = bag1 + bag2, items exceed
a.out: /home/lw/ttttttest/ttt1/execrise/exe12/bag1.cpp:94: main_savitch_3::bag main_savitch_3::operator+(const main_savitch_3::bag&, const main_savitch_3::bag&): Assertion `b1.size( ) + b2.size( ) <= bag::CAPACITY' failed.
已放弃 (核心已转储)
Data Structures and Other Objects Using C++ ( Fourth Edition ) Michael Main, Walter Savitch. p179 ↩︎