Reliable Software Logo

C++ In Action: Language

Exercise Solutions

  1. The first solution is to create the two worlds in a loop:
    for (int i = 1; i < 3; ++i)
        World world (i);
    						
    The second possibility is to open a separate local scope for each world:
    int main ()
    {
        {
            World world (1);
        }
        {
            World world (2);
        }
    }
  2. The problem is in the order of initialization of data members. Despite the ordering of initializers in the preamble to the constructor, _hand will be initialized before _n because that’s the order in which they are embedded in Glove. Therefore _n shouldn’t be passed as an argument to the Hand’s constructor because its value hasn’t been set at that point. One way of fixing this bug is to change the order of embeddings. The other is to use cFingers instead of _n to initialize the _hand.
  3. Bars.
    class HorBar
    {
    public:
        HorBar (int n)
        {
            std::cout << "+";
            for (int i = 0; i < n; ++i)
                std::cout << "-";
            std::cout << "+\n";
        }
    };
    
    class VerBar
    {
    public:
        VerBar (int n)
        {
            for (int i = 0; i < n; ++i)
                std::cout << "|\n";
        }
    };
    
    class Frame
    {
    public:
        Frame (int hor, int ver)
        : _upper (hor),
          _ver (ver),
          _lower (hor)
        {}
    private:
        HorBar _upper;
        VerBar _ver;
        HorBar _lower;
    };
  4. Ladder
    class Ladder
    {
    public:
        Ladder (int hor, int ver)
        : _upper (hor, ver),
          _middle (ver),
          _lower (hor, ver)
        {}
    private:
        Frame                _upper;
        VerBar                _middle;
        Frame                _lower;
    };
    						
  5. This particular solution that uses only the constructs introduced in chapter 1.
    int main ()
    {
        InputNum num;
        int factorial = 1;
        for (int i = 2; i < num.GetValue (); ++i)
            factorial = factorial * i;
        factorial = factorial * num.GetValue ();
        std::cout << num.GetValue () << "! = " 
                            << factorial << std::endl;
    }
  6. Planet
    class Planet: public CelestialBody
    {
    public:
        Planet (double mass, double albedo)
            : CelestialBody (mass),
              _albedo (albedo)
        {
            std::cout << "Creating a planet with albedo "
                    << _albedo << std::endl;
        }
        ~Planet ()
        {
            std::cout << "Destroying a planet with albedo "
                    << _albedo << std::endl;
        }
    private:
        double _albedo;
    };
    						
  7. The first part:
    class Two
    {
    public:
        Two ()
        {
            std::cout << "Program ";
        }
    };
    
    class Three
    {
    public:
        Three ()
        {
            std::cout << "objects ";
        }
    };
    
    class Four
    {
    public:
        Four ()
        {
            std::cout << "makes ";
        }
    };
    
    class One: public Two
    {
    public:
        One ()
        {
            Three three;
            std::cout << "with class. ";
        }
    private:
        Four    _four;
    };
    						
    The second part can be implemented like this:
    class One: public Two
    {
    public:
        One ()
        {
            std::cout << "class ";
        }
        ~One ()
        {
            std::cout << "class ";
        }
    private:
        Three            _three;
        Four            _four;
        Five            _five;
    };
    
    int main ()
    {
        One one;
        std::cout << std::endl;
    }
    
    where the classes Two, Three, Four and Five print “Program “, “makes “, “objects “ and “with “, respectively.
  8. Average.
    class Average
    {
    public:
        Average ()
            : _sum (0), _count (0)
        {}
        void Put (double n)
        {
            _sum = _sum + n;
            ++_count;
        }
        double Get () const
        {
            return _sum / _count;
        }
    private:
        double  _sum;
        int     _count;
    };
  9. The hierarchy of classes should look like this:
    class LivingBeing {};
    class Human: public LivingBeing {};
    class Tomato: public LivingBeing {};
    class Elephant: public LivingBeing {};
    						
    or you may be more thorough and separate the flora from the fauna:
    class LivingBeing {};
    class Plant: public LivingBeing {};
    class Animal: public LivingBeing {};
    class Human: public Animal {};
    class Elephant: public Animal {};
    class Tomato: public Plant {};
    
  10. Here’s the sketch of the classes mentioned in the exercise:
    class NoseHair {};
    
    class Nose
    {
    ...
    private:
        NoseHair _noseHair;
    };
    
    class Head
    {
    ...
    private:
        Nose _nose;
    };
    
    class Human
    {
    ...
    private:
        Head _head;
    };
    
    class Man: public Human {};
    class Woman: public Human {};