Breaking a sketch into multiple files

My sketch is getting long and I would like to break it up into smaller files.
The following is a simplified example.

example0 compiles.

example0:

#include <Ca.h>
#include <Cb.h>

Ca a;           //simplifed from 300 lines of instantiations
Cb b(a);        //simplifed from 100 lines of instantiations dependent on the 300 lines

void setup() { }

void loop() { }

Object ‘a’ must be instantiated before object ‘b’ due to a dependency.
example1 attempts to break the instantiations out into two files.
The verbose error message from example1 is in the following post.

example1.ino:

//#include <Ca.h>
//#include <Cb.h>

//#include "a.cpp"
//#include "b.cpp"


void setup() { }

void loop() { }

a.cpp and b.cpp are in the example1 sketch folder (they are not library).

example1/a.cpp:

#include <Ca.h>

Ca a;

example1/b.cpp:

#include "a.cpp"
#include <Cb.h>

Cb b(a);

The the library has the following two files.

Ca.h:

#ifndef CA_H
#define CA_H

class Ca
{
};
#endif

Cb.h:

#ifndef CB_H
#define CB_H

#include <Ca.h>

class Cb
{
    private:
        Ca& refCa;
    public:
        Cb(Ca& refCa) : refCa(refCa) {}
};
#endif

How would you link the example1 files?

Thank you.

Here are the first and last parts of the example1 verbose error message:

Arduino: 1.6.7 (Linux), TD: 1.27, Board: "Teensy 2.0, Keyboard + Mouse + Joystick, 16 MHz, US English"

/opt/arduino-1.6.7/arduino-builder -dump-prefs -logger=machine -hardware "/opt/arduino-1.6.7/hardware" -tools "/opt/arduino-1.6.7/tools-builder" -tools "/opt/arduino-1.6.7/hardware/tools/avr" -built-in-libraries "/opt/arduino-1.6.7/libraries" -libraries "/home/wolfv/Documents/Arduino/libraries" -fqbn=teensy:avr:teensy2:usb=hid,speed=16,keys=en-us -ide-version=10607 -build-path 

...

"/opt/arduino-1.6.7/hardware/tools/avr/../avr/bin/avr-gcc" -Os -Wl,--gc-sections,--relax  -mmcu=atmega32u4 -o "/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/example1.ino.elf" "/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/sketch/a.cpp.o" "/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/sketch/b.cpp.o" "/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/sketch/example1.ino.cpp.o" "/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/core/core.a" "-L/tmp/build60fd99ab87aa22a11390541db7f90254.tmp" -lm
/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/sketch/b.cpp.o:(.bss.a+0x0): multiple definition of `a'
/tmp/build60fd99ab87aa22a11390541db7f90254.tmp/sketch/a.cpp.o:(.bss.a+0x0): first defined here
/opt/arduino-1.6.7/hardware/tools/avr/bin/../lib/gcc/avr/4.8.1/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
collect2: error: ld returned 1 exit status
Using library file_order in folder: /home/wolfv/Documents/Arduino/libraries/file_order (legacy)
exit status 1
Error compiling.

I'm not sure what you're trying to do.

Look up "forward declarations". That allows you to declare that something exists, without actually having the something right there. You can have a class refer to an object which uses the first class by declaring them both first, then the implementation of each one can be written in any order.

You don't seem to have the concept of "library" correct. You should only #include the .h file. That is an example of a forward declaration. You use the .h file to say that this thing exists but you don't normally put any code into the .h that implements the thing. Both the main .ino and the .cpp file need to include the .h file.

You should also look up the definition of extern. That allows you to declare a variable and share it across multiple files.

Thanks MorganS, extern is exactly what was needed.
The following sketch works:

example1.ino:

#include <Cb.h>
extern Cb b;

void setup()
{
    Serial.begin (115200);
    
    b.refCa.print();
}

void loop() { }

a.cpp and b.cpp are in the example1 sketch folder (they are not library).

example1/a.cpp:

#include <Ca.h>

Ca a;

example1/b.cpp:

#include <Cb.h>
extern Ca a;

Cb b(a);

The the library has the following two files.

Ca.h:

#ifndef CA_H
#define CA_H
#include <Arduino.h>

class Ca
{
    public:
        void print() { Serial.println("in Ca"); }
};
#endif

Cb.h:

#ifndef CB_H
#define CB_H

#include <Ca.h>

class Cb
{
    public:
        Ca& refCa;
        Cb(Ca& refCa) : refCa(refCa) {}
};
#endif

Output:

in Ca

This is where the sloppy treatment of declare versus define makes a difference. When you define a variable, you do two basic things: 1) you create an attribute list for the variable (e.g., an ID, data type, scope, etc.) and 2) you define storage for it. With a declaration, you only create the attribute list.

In your situations, you might define a variable in file #2, but you need to use it in file #1. That is, the definition is in file #2. So file #2 has:

            // File #2
// ...a bunch of missing code...

int fileHandle;      // This defines fileHandle

Then in File #1 you have:

            // File #1
// ...a bunch of missing code...

   fileHandle = SD.open(fileName);

However, because the compiler doesn't know about the definition in File #2, it issues an undefined or out-of-scope error message. The fix is as MorganS said:

            // File #1

extern int fileHandle;          // A declaration of fileHandle

// ...a bunch of missing code...

   fileHandle = SD.open(fileName);

Simply stated, the declaration of fileHandle using the extern keyword says: "Compiler: I have defined fileHandle in another file, but let me use it here as an int. The linker will supply the missing memory address later on."

The moral: declare and define are two different things and most of the time programmers misuse declare when they really mean define. The key difference is that a definition both creates an attribute list and allocates memory for the variable. A declaration (e.g., a function prototype, or extern) only supplies an attribute list; no memory is allocated.