Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

This is a c++ code Understand the Problem boolean functions can be fully described by an array of bools, where the input of the function

This is a c++ code
Understand the Problem
boolean functions can be fully described by an array of bools, where the input of the function is the int index to the array, and the output is the bool value stored in that index position. We are going to wrap such an array of bools into a class called BooleanFunc (which, of course, stands for boolean function). This will represent a boolean function of any non-negative size and take precautionary measures that you would expect of a wrapper class that surrounds an unstructured type such as an array. Our goal will be to define the logic of a seven-segment display which is little more than seven boolean functions wrapped in a device that can be viewed visually.
We could do the entire project with two classes, BooleanFunc and SevenSegmentDisplay, but we will find that it is simpler to break the functionality of SevenSegmentDisplay into four classes, two of which we'll do this week (MultiSegmentLogic and SevenSegmentLogic) and two of which we'll do next week (SevenSegmentImage and SevenSegmentDisplay).
BooleanFunc will hold the truth table in a dynamic 1-D array of type bool. As we know from the modules, this tells us what the output is for any integer input, and those integer inputs are the encoded binary bits going into the table. The class allows the instantiation of any non-negative sizeboolean function, and once instantiated, cannot be resized (no mutator for the table size), but it can be redefined (meaning the operator=() and copy constructor could result in a totally new make-up of the object which has a different table size). Of course, it protects itself against client abuse and manages dynamic memory without leaking anything.
We will define a general base class called MultiSegmentLogic, which can be extended to cover a multi-segment display having any number of segments, but our intent is to extend it to cover a seven-segment display. We will be thinking in terms of the seven-segment display throughout the design of the class, but we'll design MultiSegmentLogic so that it could support a hypothetical 49-segment display, 1000-segment display or any other size the client wishes.
We will derive SevenSegmentLogic from MultiSegmentLogic, baking the specifics of a seven-segment display into this derived class.
MultiSegmentLogic, and SevenSegmentLogic are so named because they do the boolean logic of the displays, but do not actually produce any visual representation. This is not only more manageable (you would be hard pressed to do both the logic and the display in a single week), but is in keeping with the separation of interface and implementation.
Of course, we'll test our classes as we go, and you will demonstrate that your classes and methods work with a main() that tests the individual components.
Act 1: Class BooleanFunc
Summary
BooleanFunc will contain a truthTable (a dynamic array) which defines theboolean function being represented. We can load this truthTable using a mutator, setTruthTable() , and change the function it represents by calling setTruthTable() to give the table new values. We will not be able to change the size of the table (i..e. #inputs to the function) after an object is instantiated using a setTableSize-style method, but we can totally redefine the object using the assignment operator, which will have the effect of giving it a new size.. We'll need a method to evaluate the state (output) of the function based on input integers, and this will take the form or an eval( int ) method. Finally, we'll store the most recently evaluated output in an internal bool state member, so we can call eval() once, but get the resulting state later without having to re-call eval(): a method getState() will do the job nicely.
Static (Public) Members
int MAX_TABLE_FOR_CLASS = 65536; // that's 16 binary input lines
int DEFAULT_TABLE_SIZE = 16
Instance (Private) Members
int tableSize - reflects the number of inputs. tableSize of 4 would implytwo binary inputs; a size of 16 would imply four binary inputs. Since we will be using one int to act as our multi-bit input, a tableSize of 4 means the valid input ints are 0-3. Size of 16 means valid input ints are 0-15.
bool *truthTable - This is our array (to be dynamically allocated and de-allocated) whose size is tableSize.
bool evalReturnIfError - This is the state (or return value) if an illegal (out-of-range) input is presented to the object -- or if no input has yet been presented to it.
bool state - this remembers the result of the most recent call to eval( int ).
Instance (Public) Methods
Constructors and a Destructor - The constructor's signature should be BooleanFunc( int tableSize = DEFAULT_TABLE_SIZE, bool evalReturnIfError = false ). More on constructors, below.
Mutators - We set the truth table not by passing an array which is an exact copy of the function table. Rather, we choose one of two mutators:
bool setTruthTableUsingTrue( int inputsThatProduceTrue[], int arraySize ) - In other words, if the function evaluates to true only for inputs 3 and 9, we would send it an array {3, 9} of size 2. This way, even if the table is very large, we can easily set it by passing a very small array in the cases where very few inputs produce true outputs. Any indices not passed in the array parameter are assumed to represent falseoutputs for their respective table positions.
bool setTruthTableUsingFalse( int inputsThatProduceFalse[], int arraySize ) - If the most common output is true, however, then we might prefer to use this method which has the same signature as its partner but provides an array whose values represent the false-triggering inputs. For example, if the truth table had size 64, and we wanted to represent a function "greater than 3", we would use setTruthTableUsingFalse(), and send it the array {0, 1, 2, 3}. Any indices not passed in the array parameter are assumed to represent trueoutputs for their respective table positions.
The return value of these two methods is true as long as the passed-in array size is <= the truth table array, and false, otherwise.. However, if a bad int is passed inside the array parameter (e.g., {5, 0, 2, 19} in the case of a 16-element truth table), we'll just ignore the bad int (19) and process the other good ints that are passed (5, 0 and 2).
bool eval( int input ) and bool getState() - a mutator for the statemember based on the an input integer, which also returns that evaluated state, and an accessor for the state. If an invalid input is presented to eval(), evalReturnIfError is assigned to state and returned.
Deep memory methods - A copy constructor, destructor and assignment operator.
Supply helper methods as appropriate.
Sample Client
Here is some client code to use while debugging. You should be able to determine the correct run that results. You should provide some code that is more complete than this in your testing.
BooleanFunc segA, segB( 13 ), segC( 100, true );
int evenFunc[] = { 0, 2, 4, 6, 8, 10, 12, 14 }, inputX;
short sizeEvenFunc = sizeof(evenFunc) / sizeof(evenFunc[0]);
int greater9Func[] = { 10, 11, 12, 13, 14, 15 };
short sizeGreater9Func = sizeof(greater9Func) / sizeof(greater9Func[0]);
int greater3Func[] = { 0, 1, 2, 3 };
short sizeGreater3Func = sizeof(greater3Func) / sizeof(greater3Func[0]);
segA.setTruthTableUsingTrue( evenFunc, sizeEvenFunc );
segB.setTruthTableUsingTrue( greater9Func, sizeGreater9Func );
segC.setTruthTableUsingFalse( greater3Func, sizeGreater3Func );
// testing class BooleanFunc
cout << "before eval() ";
cout
<< " A(x) = "
<< segA.getState()
<< " B(x) = "
<< segB.getState()
<< " C(x) = "
<< segC.getState()
<< endl << endl;
cout << "looping with eval() ";
for ( inputX = 0; inputX < 10; inputX++ )
{
segA.eval( inputX );
segB.eval( inputX );
segC.eval( inputX );
cout
<< "Input: " << inputX
<< " A(x) = "
<< segA.getState()
<< " B(x) = "
<< segB.getState()
<< " C(x) = "
<< segC.getState()
<< endl << endl;
}
segA.eval( inputX );
Act 2: Class MultiSegmentLogic
Summary
MultiSegmentLogic encapsulates any number of segments as a dynamic array of BooleanFunc objects and allows them to work together to produce some multi-segment display. Upon instantiation, a MultiSegmentLogic object obtains its size (the number of segments) from the user. This can be changed (a major resetting of the object) through the mutator setNumSegs(). After construction, or a resetting of the object via setNumSegs(), the truth table for each segment needs to be loaded, which is done using mutator setSegment(). setSegment() sends a BooleanFunc to a particular segment. For a seven segment display this would have to be called seven times, once for each segment. We'll do that in the derived class (Act 3), not in the client.
Static (Public) Members
(None are needed.)
Instance (Protected) Members
int numSegs - the number of BooleanFuncs (i.e., segments) that this potential display logic encapsulates. We think of this as being 7, but it can be any positive int.
BooleanFunc *segs - This is our array (to be dynamically allocated and de-allocated) whose size is numSegs.
Instance (Public) Methods
Constructors and a Destructor - The constructor's signature should be MultiSegmentLogic( int numSegs = 0 ). It has to allocate an array of numSegs BooleanFuncs. More on constructors, below.
Mutators - One that sets the number of segments and one that loads the truth table for a particular segment:
bool setNumSegs( int numSegs ) - this is a fairly serious mutator, which must completely redefine the kind of display, wiping out old segments and reallocating the new number of segments, leaving each in a default state. This is called, for example, when changing from a 7 segment to 12 segment display. Any non-negative value is allowed.
bool setSegment( int segNum, BooleanFunc &funcForThisSeg ) - it sets segs[segNum] to the passed-in BooleanFunc. It filters bad segNum and takes appropriate action.
void eval( int input ) - calls eval() for each of the segs in the object.
Deep memory methods - A copy constructor, destructor and assignment operator.
Supply helper methods as appropriate.
Sample Client
You can create and test your own sample client, but don't hand it in. I want to see the sample client of the derived class, SevenSegmentLogic, which will implicitly test MultiSegmentLogic.
Act 3: Derived Class SevenSegmentLogic
Summary
This class is derived from MultiSegmentLogic. It has no new members but adds the specifics of seven segment display logic, namely the number of segments (= 7) and the actual truth tables for a seven-segment display.
Static (Public) Members
(None are needed.)
Instance (Protected) Members
(None are needed.)
Instance (Public) Methods
Default Constructor - Simply sets the number of segments to 7 (literal ok) and the loads the BooleanFuncs for each of the seven segments using a helper (see below).
bool getValOfSeg( int seg ) - Returns whatever is in the state variable of that segment. Of course checks for valid parameter.
Helper methods
You will need some private helpers to load the segments, called somewhere in the constructor. Ultimately, somewhere you'll need to call setSegment( k, bFunc) for k = 0 through 6, where bFunc is the boolean function for the kth segment. For example, if a, b, c, d, e, f and g, are the universal names for the segments, let's say that you associate segs[0] a, segs[1] b, segs[2] cand so on. The boolean function for segment a (your segs[0]) is easily found along with all the others, on-line. Here is the truth table for segment a:
"a" bit (7-segment display)
input output
0 T
1 F
2 T
3 T
4 F
5 T
6 T
7 T
8 T
9 T
10 T
11 F
12 T
13 F
14 T
15 T
You would, therefore, instantiate a BooleanFunc that realizes this truth table (using the BooleanFunc mutator setTruthTableUsing...()) then pass that BooleanFunc object to the setSegment() method of the base class. All of this is done in the helper function.
Here is some client code use while debugging. You should be able to determine the correct run that results. You should provide some code that is more complete than this in your testing. This example tests the copy constructor as well as the other methods.
int inputX, k;
SevenSegmentLogic my7Seg;
SevenSegmentLogic myCopy( my7Seg );
for ( inputX = 0; inputX < 16; inputX++ )
{
myCopy.eval( inputX );
cout << " | ";
for ( k = 0; k < 7; k++ )
cout << myCopy.getValOfSeg( k ) << " | ";
cout << endl;
}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions