Unit 2330 (BNE Only) and EP353 Tutorial on Inheritance

advertisement
Unit 2330 Object Oriented Design
Second Assignment contributing 50% to the unit mark.
Deadline - To be determined
This is an individual assignment.
The following questions are to be considered as components of a single assignment.
When attempting these questions they should be incorporated into one finished assignment rather than
treating them as a number of loosely related questions.
To achieve a pass you must incorporate into your assignment the features outlined in questions 1 to 14
inclusive.
Additional marks will be awarded for the features outlined in questions 15 onwards and any extra
features you may add. Marks will be dependent on the relevance and sophistication of the features, the
quality of the overall design and its implementation
You should submit a report which shows your class designs and explains the issues raised in each of
the questions and should relate them to your solution. You need not hand in your C++ program listing
unless specifically requested by the lecturer. You will also be required to demonstrate and explain your
solution.
Submission Date. End of week 12 of semester 2. All work is to be handed in at the school office in the
usual manner. This assignment counts for 50% of the unit (there is no exam in this subject)
1.
Create a base class called ‘CPU’, and using suitable private member variables, record the
following information or characteristics common to all CPU
 Clock speed in MHz
 Cache size in Kbytes
 Pin Out Type e.g. 1 = Socket 7, 2 = Slot A etc.
 Manufacturer Name both as a string (e.g. “Intel”, “AMD” etc). Use the string class
from the standard template library (i.e. ‘#include <string>’ and ‘using namespace
std;’
 Model Name, both as a string, e.g. “PIII”, “PIV”, “Athlon” etc.
2.
Create a Constructor for your CPU class that is able to accept, as arguments, all information
required to initialise the member variables declared above. In this case your constructor will
accept 5 arguments.
3.
Create the following public member functions for your CPU class.
 void Identify(void) This should print out all the values assigned to your member
variables.
 int GetClockSpeed() This should return the clock speed in MHz
 int GetCacheSize() This should return the cache size on Kbytes
 … etc for all other member variables.
4.
Now create two new intermediate classes called IntelCPU and AmdCPU by inheriting from
the base class CPU. Write suitable new constructors for these new classes, which call their
base class constructor.
Note that the constructor for these new classes will also have to be written to accept whatever
arguments that may be required to initialise their base class (See CPU constructor), however,
because these new classes are more specialised versions of the CPU class their constructors
will require fewer arguments. For example, the IntelCPU constructor should know that its
Manufacturers name is “Intel” and thus its constructors should require fewer arguments than
the base class constructor, ditto the AmdCPU.
5.
Finish off by creating a complete classification/hierarchy for a representative sample of CPUs.
Eventually you may end up with a fully specified class such as IntelPIIISlotA which means an
Intel Pentium III with a Slot A interface. The clock speed of the CPU is to be defined at run
time via an argument to the constructor when the object is created. E.g. IntelPIIISlotA
mycpu(800); for an 800 Mhz model
As you create these new derived classes, remember to write new constructors which call their
immediate base or parent class’s constructor. If you have done this correctly, you will find
that the constructors lower down the classification/hierarchy tree require progressively fewer
arguments that those above them (i.e. their parent or base class) until ultimately, the
constructors for the classes at the lowest points in your hierarchy require no (or perhaps just a
few, depending upon how far you want to take it) arguments.
6.
Now think about ways in which a Cpu with the characteristics of Intel Pentium III running at
800 MHz in an Slot A pin out could actually be created as an object or class instance in your
program. Obviously we could say something like this which creates an instance of exactly that
type of class
main() {
IntelPIIISlotA mycpu(800);
mycpu.Identify() ;
}
But think about how we could create CPUs with characteristics identical to the IntelPIIISlotA
by creating instance of classes higher up the hierarchy than this e.g. IntelPIII, or IntelCPU or
even just CPU, now compare each of these approaches and think about what inheritance has
achieved for as a tool for specifying correctness of construction.
7.
Verify that the functions that you have written in your base class CPU have all been inherited
and thus can be applied to instances of all classes further down the hierarchy i.e. verify that
functions/methods defined in the base class work regardless of whichever kind of CPU we
apply them to.
8.
If you were adding functions/methods to simulate the operation of a CPU such as Reset(),
where would you position the code for this function in your classification hierarchy?
Remember, classification is a process that attempts to isolate commonality and move it as far
up the classification hierarchy a possible.
9.
If you were adding functions/methods to simulate the actual instructions that each kind of
CPU could execute how would you represent these functions in your class hierarchy, given
that Intel and AMD have some instructions in common and some that are unique to their
particular manufacturer (e.g. 3D Now! Instructions are unique to Amd while MMX
instructions are unique to Intel)? Generate some dummy instructions to simulate this concept.
10. Suppose AMD Introduced a new processor the AthlonXP which had a new characteristic
never seen before in any CPU, let’s say a level 3 cache of 64Kytes in size. In which class in
your hierarchy would you position this new member variable to represent the new cache,
given that all classes beneath that class will inherit this new feature? How would this change
affect your constructor for that class?. How, if at all, would it affect the constructors of the
classes lower down the hierarchies?.
11. Implement point 10) above by creating a new class AthlonXP with the new cache, and then,
using inheritance, create additional classifications for a family of AthlonXP CPUs such as
AthlonXP1500, AthlonXP1600, AthlonXP1700 etc.
Suppose then that you introduced an instance of one these classes into your program and then
invoked the Indentify() function (inherited from the base class CPU) for it. Why do you not
see the information about the new Cache Size in the display? What changes would you make
to ensure that when a kind of AthlonXP CPU was being asked to identify itself, the new cache
size information appeared in the display but does not appear for any other kind of CPU?
(Hint: think about the possibility of overriding an inherited base class function within a
derived class while still re-using as much as possible of it).
12. Attempt to implement classifications for other CPU components such as motherboards, disk
drives, memory chips, graphics, sound, modem cards etc. Use your imagination, consult a PC
magazine or the ‘internet’ for ideas.
13. Suppose you now created a PC class that maintained pointers to its member objects e.g. a
pointer to its CPU, a pointer to its motherboard, hard-disk etc. Given that at this time (i.e.
Design time) you do not know which actual kind of CPU, motherboard, hard disk etc will
eventually be installed into the PC when it is constructed, what kind of pointers should you
use and why? Try to implement this PC class with suitable pointers and a suitable constructor
to initialise/construct the CPU
14. Write an Identify() function for your PC class that when invoked sends Identify() messages to
each of the components within the PC asking them to identify themselves, thus resulting in a
display of the complete spec of the PC and all its components.
15. Suppose you now created an AthlonXP CPU such as an AthlonXP1500 and then assigned this
to your new PC during its construction. When a message is sent to the PC asking it to identify
itself, the message sent to the AthlonXP’s ‘Identify()’ function does not work correctly,
because it does not print out the information relating to the new cache size for this kind of
CPU, why is this? How would correct this?.
16. Write a suitable family of upgrade functions e.g. UpgradeCPU(), UpgradeMotherboard() etc.
that could be used to simulate the upgrading of the components of a PC. Such functions
should be written to accept a pointer to the new kind of component which is going to be
swapped into the PC and should return a pointer to the existing object which is being
removed/upgraded. Who has to take responsibility for deleting the old object? What happens
if nobody deletes it?
17. Suppose your motherboard was a Slot A motherboard, i.e. it could only take CPU with a Slot
A pin-out. Now suppose you wanted to make sure that only Slot A CPUs could be fitted to a
PC with a Slot A motherboard how would you achieve this (hint: look up Dynamic_cast
operator in the help for Visual C++). Furthermore, how would this important design
consideration affect the design of your Cpu/motherboard hierarchy/classification?
18. Given that your PC encapsulates its components using generic base-class pointers, why is it
important to make sure that the destructors for your base classes are made virtual, (Hint: think
about what happens when a PC is destroyed. How does the PC class destructor make sure that
all the components within it, such as the CPU, motherboard, disk etc. are destroyed also, given
that the PC class doesn’t actually know until run-time what actual instances of these
components it has been fitted with).
19. Create a class hierarchy to represent different kinds of PC. For example you could organise
them by manufacturer, with Dell, Compaq, Mesh, Evesham have the PC class as their base or
parent class, then you could create sub-classifications for each manufacturer to represent their
particular models.
For example, you could create a class called MeshXP1800-Ti500 meaning a kind of PC
manufactured by ‘Mesh’, which is fitted with an AthlonXP1800 CPU and a nVidia TI500
graphics card (and of course other components such as disk, modem etc).
How would you write constructor for each of your classes to make sure it is only constructed
with the correct components for that model. For example how you make sure that a
MeshXP1800-Ti500 is fitted only with a AthlonXP1800 CPU and an nVidia Ti-500 graphics
card when it is constructed? How would you write the UpgradeCPU() function to make sure
that it can only be fitted with a kind of AthlonXP cpu? (Hint think again about the
Dynamic_cast operator and the need to make the Upgrade functions virtual in the PC base
class.
Assessment
Marks will be awarded for completeness, UML diagrams, working state of program,
design of classes, use of the C++ language, program documentation and report.
Typically:
 40-49% may be achieved for completing a basic design and implementation
with a satisfactory C++ program.
 50-59% requires completion of a basic design and implementation with good
use of C++ and an attempt at adding the additional features in questions 15
onwards with varying degrees of success.
 60-69% requires good design and very good use of C++ with all of the
additional features in questions 15 onwards implemented successfully.
 70%+ requires all of the above and additional features demonstrating
outstanding creativity and innovation in the use of object oriented design and
implementation using C++
In all cases the program will also be assessed for good documentation, layout and
structure.
Note: The program must be demonstrated before any marks will be awarded.
Download