I'm working my way through a C++ book (again), and am up to a section on composition.

The book (Deitel) strongly recommends keeping such objects private: "[making member objects public] does violate the encapsulation and hiding of the containing class's implementation, so member objects of class types should still be private, like all other data members."

When making a fun test program using this concept, making six classes that will be utilized by a "top" class, I noticed the number of functions in that top class needed to access all the features of those six objects blew up really quickly. (See example below).

So my questions are:
1) Is the Deitel advice applicable to a self-contained program, or more for classes intended for distribution?
2) If the latter, is it acceptable to make member objects public for easier access?
3) Or are there other mechanisms that eliminate this overhead that I haven't gotten to yet?

Example:
Let's say we have three classes:

Code:
class ClassA
{
public:
   int getA1();
   int getA2();
   int getA3();
   void setA1( int );
   void setA2( int );
   void setA3( int );
private:
   int a1;
   int a2;
   int a3;
};

class ClassB
{
public:
   int getB1();
   int getB2();
   int getB3();
   void setB1( int );
   void setB2( int );
   void setB3( int );
private:
   int b1;
   int b2;
   int b3;
};

class ClassC
{
public:
   int getC1();
   int getC2();
   int getC3();
   void setC1( int );
   void setC2( int );
   void setC3( int );
private:
   int c1;
   int c2;
   int c3;
};
If we make member objects of these private in TopLevel:

Code:
class TopLevel
{
public:
   /* constructor and member initializers */

   int getA1() { return a.getA1(); }
   int getA2() { return a.getA2(); }
   int getA3() { return a.getA3(); }

   int setA1( int a1 ) { a.setA1( a1 ); }
   int setA2( int a2 ) { a.setA2( a2 ); }
   int setA3( int a3 ) { a.setA3( a3 ); }

   int getB1() { return b.getB1(); }
   int getB2() { return b.getB2(); }
   int getB3() { return b.getB3(); }

   int setB1( int b1 ) { b.setB1( b1 ); }
   int setB2( int b2 ) { b.setB2( b2 ); }
   int setB3( int b3 ) { b.setB3( b3 ); }

   int getC1() { return c.getC1(); }
   int getC2() { return c.getC2(); }
   int getC3() { return c.getC3(); }

   int setC1( int c1 ) { c.setC1( c1 ); }
   int setC2( int c2 ) { c.setC2( c2 ); }
   int setC3( int c3 ) { c.setC3( c3 ); }

   /* additional TopLevel functions */

private:
   ClassA a;
   ClassB b;
   ClassC c;
};
...but if we make them public, it can be simplified to:

Code:
class TopLevel
{
public:
   /* constructor and member initializers */

   /* additional TopLevel functions */

   ClassA a;
   ClassB b;
   ClassC c;
};