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.