Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++
Prev Contents / Index Next

Exercises

Solutions to selected exercises can be found in the electronic document The Thinking in C++ Annotated Solution Guide, available for a small fee from www.BruceEckel.com.

  1. Modify Car.cpp so that it also inherits from a class called Vehicle, placing appropriate member functions in Vehicle (that is, make up some member functions). Add a nondefault constructor to Vehicle, which you must call inside Car’s constructor.
  2. Create two classes, A and B, with default constructors that announce themselves. Inherit a new class called C from A, and create a member object of B in C, but do not create a constructor for C. Create an object of class C and observe the results.
  3. Create a three-level hierarchy of classes with default constructors, along with destructors, both of which announce themselves to cout. Verify that for an object of the most derived type, all three constructors and destructors are automatically called. Explain the order in which the calls are made.
  4. Modify Combined.cpp to add another level of inheritance and a new member object. Add code to show when the constructors and destructors are being called.
  5. In Combined.cpp, create a class D that inherits from B and has a member object of class C. Add code to show when the constructors and destructors are being called.
  6. Modify Order.cpp to add another level of inheritance Derived3 with member objects of class Member4 and Member5. Trace the output of the program.
  7. In NameHiding.cpp, verify that in Derived2, Derived3, and Derived4, none of the base-class versions of f( ) are available.
  8. Modify NameHiding.cpp by adding three overloaded functions named h( ) to Base, and show that redefining one of them in a derived class hides the others.
  9. Inherit a class StringVector from vector<void*> and redefine the push_back( ) and operator[] member functions to accept and produce string*. What happens if you try to push_back( ) a void*?
  10. Write a class containing a long and use the psuedo-constructor call syntax in the constructor to initialize the long.
  11. Create a class called Asteroid. Use inheritance to specialize the PStash class in Chapter 13 (PStash.h & PStash.cpp) so that it accepts and returns Asteroid pointers. Also modify PStashTest.cpp to test your classes. Change the class so PStash is a member object.
  12. Repeat Exercise 11 with a vector instead of a PStash.
  13. In SynthesizedFunctions.cpp, modify Chess to give it a default constructor, copy-constructor, and assignment operator. Demonstrate that you’ve written these correctly.
  14. Create two classes called Traveler and Pager without default constructors, but with constructors that take an argument of type string, which they simply copy to an internal string variable. For each class, write the correct copy-constructor and assignment operator. Now inherit a class BusinessTraveler from Traveler and give it a member object of type Pager. Write the correct default constructor, a constructor that takes a string argument, a copy-constructor, and an assignment operator.
  15. Create a class with two static member functions. Inherit from this class and redefine one of the member functions. Show that the other is hidden in the derived class.
  16. Look up more of the member functions for ifstream. In FName2.cpp, try them out on the file object.
  17. Use private and protected inheritance to create two new classes from a base class. Then attempt to upcast objects of the derived class to the base class. Explain what happens.
  18. In Protected.cpp, add a member function in Derived that calls the protected Base member read( ).
  19. Change Protected.cpp so that Derived is using protected inheritance. See if you can call value( ) for a Derived object.
  20. Create a class called SpaceShip with a fly( ) method. Inherit Shuttle from SpaceShip and add a land( ) method. Create a new Shuttle, upcast by pointer or reference to a SpaceShip, and try to call the land( ) method. Explain the results.
  21. Modify Instrument.cpp to add a prepare( ) method to Instrument. Call prepare( ) inside tune( ).
  22. Modify Instrument.cpp so that play( ) prints a message to cout, and Wind redefines play( ) to print a different message to cout. Run the program and explain why you probably wouldn’t want this behavior. Now put the virtual keyword (which you will learn about in Chapter 15) in front of the play( ) declaration in Instrument and observe the change in the behavior.
  23. In CopyConstructor.cpp, inherit a new class from Child and give it a Member m. Write a proper constructor, copy-constructor, operator=, and operator<< for ostreams, and test the class in main( ).
  24. Take the example CopyConstructor.cpp and modify it by adding your own copy-constructor to Child without calling the base-class copy-constructor and see what happens. Fix the problem by making a proper explicit call to the base-class copy constructor in the constructor-initializer list of the Child copy-constructor.
  25. Modify InheritStack2.cpp to use a vector<string> instead of a Stack.
  26. Create a class Rock with a default constructor, a copy-constructor, an assignment operator, and a destructor, all of which announce to cout that they’ve been called. In main( ), create a vector<Rock> (that is, hold Rock objects by value) and add some Rocks. Run the program and explain the output you get. Note whether the destructors are called for the Rock objects in the vector. Now repeat the exercise with a vector<Rock*>. Is it possible to create a vector<Rock&>?
  27. This exercise creates the design pattern called proxy. Start with a base class Subject and give it three functions: f( ), g( ), and h( ). Now inherit a class Proxy and two classes Implementation1 and Implementation2 from Subject. Proxy should contain a pointer to a Subject, and all the member functions for Proxy should just turn around and make the same calls through the Subject pointer. The Proxy constructor takes a pointer to a Subject that is installed in the Proxy (usually by the constructor). In main( ), create two different Proxy objects that use the two different implementations. Now modify Proxy so that you can dynamically change implementations.
  28. Modify ArrayOperatorNew.cpp from Chapter 13 to show that, if you inherit from Widget, the allocation still works correctly. Explain why inheritance in Framis.cpp from Chapter 13 would not work correctly.
  29. Modify Framis.cpp from Chapter 13 by inheriting from Framis and creating new versions of new and delete for your derived class. Demonstrate that they work correctly.


[51] In Java, the compiler won’t let you decrease the access of a member during inheritance.

[52] To learn more about this idea, see Extreme Programming Explained, by Kent Beck (Addison-Wesley 2000).

[53] See Refactoring: Improving the Design of Existing Code by Martin Fowler (Addison-Wesley 1999).

Thinking in C++
Prev Contents / Index Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire