Clases dentro de Clases
Una clase puede ser el atributo de otra clase.
Veamos como metemos la clase soldado dentro del tanque, esta seria la cabecera:
/**
* Tanque.hpp
* Clase que define el objeto Tanque . El objeto tanque estara lleno
* de Objeto soldados, lo que nos sirve para demostrar el uso de clases
* como atributos, etc..
*
* Pello Xabier Altadill Izura
*
*/

#include <iostream.h>
#include "Soldado.hpp"

class Tanque {
    public:
        // constructores
        Tanque();
        Tanque(char *nombre, int proyectiles,Soldado soldado);
        // destructor
        ~Tanque();
        // copia
        Tanque(Tanque const &);

        // get/set
        char *getNombre () const { return this->nombre; }
        void setNombre (char *nombre) { this->nombre = nombre; }
        int getProyectiles () const { return this->proyectiles; }
        void setProyectiles (int proyectiles) { this->proyectiles = proyectiles; }
        Soldado getSoldado () const { return this->soldado; }
        void setSoldado (Soldado soldado) { this->soldado = soldado; }

        void avanzar(int metros) const;
        void disparar();

    private:
        char *nombre;
        int proyectiles;
        Soldado soldado;
};
Y su implementacion:
/**
* Tanque.cpp
* Programa que implementa la clase Tanque
*
* Pello Xabier Altadill Izura
* Compilacion: g++ Tanque.cpp -o Tanque
*/

#include "Tanque.hpp"

        // Constructor
        Tanque::Tanque(): nombre("Supertanque"), proyectiles(10), soldado(Soldado()) {
                cout << "-clase Tanque- Tanque " << nombre <<
" construido. Proyectiles: " << proyectiles << endl;
        }

        // Constructor parametrizado
        Tanque::Tanque(char *nombre, int proyectiles, Soldado soldado) {
                this->nombre = nombre;
                this->proyectiles = proyectiles;
                this->soldado = soldado;
                cout << "-clase Tanque- " << nombre << " :Tanque
construido. Proyectiles: " << proyectiles << endl;
        }

        // Destructor
        Tanque::~Tanque() {
                cout << "-clase Tanque- Tanque "<< this->getNombre()
<< " destruido."<< endl;
        }

        // constructor copia
        Tanque::Tanque(const Tanque & original) {
                nombre = new char;
                nombre = original.getNombre();
                cout << "-clase Tanque- Tanque copia creada."<< endl;
        }

        // metodo avanzar
        void Tanque::avanzar(int metros) const {
                cout << "-clase Tanque-" << this->getNombre() << "
avanzando:  " << metros << " m." << endl;
        }

        // metodo disparar
        void Tanque::disparar(){
                if (proyectiles > 0) {
                    proyectiles--;
                    cout << "-clase Tanque-" << this->getNombre() <<"
BOOOOM!!" << endl;
                } else {
                    cout << "-clase Tanque-" << this->getNombre() << " No queda municion." << endl;
                }
        }


// funcion principal
// Aqui haremos multiples pruebas...
int main () {

int i, resp;

// creamos los Tanques

Tanque tanqueta = Tanque();

// podemos sacar lso datos del soldado asi:
cout << "El nombre del soldado es: " << (tanqueta.getSoldado()).getNombre()<< endl;

tanqueta.avanzar(5);
tanqueta.disparar();
tanqueta.getSoldado().matar();
cin >> i;
}
friend: haciendo amigos
Mediante la palabra reservada friend podemos declara relaciones de confianza entre clases y permitir que una clase amiga pueda acceder a los atributos y metodos privados de esa clase.
Veamos el ejemplo con la Pluma y la Espada. La pluma vence a la espada pero ademas la declara como amiga porque es asi de enrollada. Veamos la declaracion de Pluma:
/**
* Pluma.hpp
* Clase que define el objeto pluma, un objeto que sirve para escribir
*
* Pello Xabier Altadill Izura
*
*/

#include <iostream.h>

class Pluma {
    public:
        Pluma();
        Pluma(char *tipo, char *usuario);
        ~Pluma();
        Pluma(Pluma const &);


        // ATENCION!!! definimos la clase ESPADA como friend
        // por tanto desde ella se podra acceder a los elementos PRIVADOS de la Pluma
        friend class Espada;

        char *getTipo() const { return this->tipo;}
        char *getUsuario() const { return this->usuario;}

    private:
        // metodo para escribir con la pluma
        void escribe (char *texto) {cout << "escribo con la pluma: " << texto << endl;}
        void test() { cout << "Mega funcion privada de Pluma!" << endl;}
        char *tipo;
        char *usuario;
};
Y su implementacion:
/**
* Pluma.cpp
* Programa que implementa la clase Pluma
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -c Pluma.cpp
*/

#include "Pluma.hpp"

        // Constructor
        Pluma::Pluma(): tipo("tinta china"), usuario("Bertrand Russel") {
                cout << "Pluma construida." << endl;
        }

        // Constructor
        Pluma::Pluma(char *tipo, char *usuario) {
                this->tipo = tipo;
                this->usuario = usuario;
                cout << "Pluma construida de tipo: " << tipo << endl;
        }

        // Destructor
        Pluma::~Pluma() {
                cout << "Pluma destruida." << endl;
        }

        // Constructor copia
        Pluma::Pluma(Pluma const & original) {
                tipo = new char;
                tipo = original.tipo;
        }



Y ahora la declaracion de la Espada
/**
* Espada.hpp
* Clase que define el objeto Espada, un objeto que sirve para matar
*
* Pello Xabier Altadill Izura
*
*/

#include <iostream.h>.h

class Espada {
    public:
        Espada();
        Espada(char *tipo);
        ~Espada();
        Espada(Espada const &);

        // desde este metodo accederemos a la
        // parte privada de la pluma
        void usarPluma (char *texto);

        char *getTipo() const { return this->tipo;}
    private:

        char *tipo;
};
Y su implementacion:
/**
* Espada.cpp
* Programa que implementa la clase Espada
*
* Pello Xabier Altadill Izura
*
* Compilacion: g++ -o Espada Pluma.o Espada.cpp
*/


#include "Espada.hpp"
#include "Pluma.cpp"

        // Constructor
        Espada::Espada(): tipo("katana") {
                cout << "Espada construida." << endl;
        }

        // Constructor
        Espada::Espada(char *tipo) {
                this->tipo = tipo;
                cout << "Espada construida de tipo: " << tipo << endl;
        }

        // Destructor
        Espada::~Espada() {
                cout << "Espada destruida." << endl;
        }

        // Constructor copia
        Espada::Espada(Espada const & original) {
                tipo = new char;
                tipo = original.tipo;
        }

        // metodo desde el que accedemos a Pluma
        void Espada::usarPluma(char *texto) {
                // implementamos una pluma y...
                Pluma plumilla = Pluma();
                // y ahora accedemos a sus miembros privados: atributos ...
                cout << "La pluma es tipo: " <<  plumilla.tipo << endl;
                cout << "Y su usuario es: " <<  plumilla.usuario << endl;
                plumilla.escribe(texto);
                // e incluso a sus metodos!
                plumilla.test();
        }

// funcion principal
int main () {
int i;
Espada tizona = Espada("mandoble");

// invocamos un metodo que accedere a la zona privada de la clase
tizona.usarPluma("jaja uso la pluma a mi antojo");

cin >> i;
return 0;
}

La funcion amiga
Podemos declarar una funcion como amiga y nos dara acceso a TODO a traves de ese funcion.
Para ilustrar esto definimos las clases Chico y Chica en un unico fichero

/**
* ChicoChica.cpp
* Clase que define el objeto Chico y Chica. Chico tiene una funcion llamada
* esNovio que dentro de chica la declaramos como friend y le dara acceso a todo
*
* Pello Xabier Altadill Izura
* Compilacion: g++ -o ChicoChica ChicoChica.cpp
*/

#include <iostream.h>

class Chico {
    public:
        // constructor
        Chico():nombre("Romeo") {}

        // constructor
        Chico(char *nombre) { this->nombre = nombre;}

        // destructor
        ~Chico() {}

        // constructor copia
        Chico(Chico const & origen) {
                nombre = new char;
                nombre = origen.nombre;
        }

        // desde este metodo accederemos a la
        // parte privada de la clase chica
        void esNovio();

        char *getNombre() const { return this->nombre;}

    private:
        char *nombre;
};

class Chica {
    public:
        // constructor
        Chica():
                nombre("Julieta"),
                edad(23),
                coeficienteInteligencia(140),
                medidas("95-60-95") {
        }

        // destructor
        ~Chica() {}

        // constructor copia
        Chica(Chica const & origen) {
                nombre = new char;
                nombre = origen.nombre;
        }

        // Aqui definimos un metodo friend externo
        // que tendra acceso a toda la clase chica
        friend void Chico::esNovio();

        // otra opcion seria declara Chico como friend:
        // friend class Chico;

    private:
        void pensar() { cout << "estoy pensado..." << endl; }
        void entrarHabitacion() { cout << "estoy entrando en la habitacion..." << endl; }
        char *nombre;
        int edad;
        int coeficienteInteligencia;
        char *medidas;
};

// implementacion de la funcion del chico esNovio
void Chico::esNovio() {
    Chica neska = Chica();

    neska.entrarHabitacion();
    cout << "Con esta funcion entro en todo! " << endl;
    cout << "Dime tu edad real chica: " << neska.edad << endl;
    cout << "Y tu coeficiente intelectual: " << neska.coeficienteInteligencia << endl;
    cout << "joder, me parece que no te gustara el futbol." << endl;
}

// funcion principal, para las pruebas
int main () {
int i;
Chico mutiko = Chico();
// vamos a ver si llamamos a esNovio...
mutiko.esNovio();

cin >> i;
}