In projects bigger than a simple Hello World more .cpp (technically called "translation units") are written, to separate logically the parts of the application and to decrease compilation times.
Notice that the different cpp files are not merged in a single main .cpp (as I suppose you think from your question), but each .cpp is compiled on its own; the compiler generates an object module (usually .o or .obj) for each .cpp, and then it's the linker is called to link together such modules to produce the final executable.
How to make this work? In little projects where you call the compiler by hand, you may just call the compiler specifying all the .cpps on the command line and let it recompile everything and call the linker by itself.
When the program grows bigger, you usually delegate the task of calling the compiler only on the modified files and then run the linker to some kind of utility: many people use Makefiles, many just use an IDE that manages all the files in a project and automagically invokes the compiler and the linker just pressing a button. Actually it's quite uncommon to manually invoke the compiler and the linker in separate steps.
To make the communication between the various modules possible, C++ allows to just declare functions/classes/variables with prototypes/extern declarations (which usually is done in header files) without actually defining them in the current translation unit. This lets the compiler check the syntax and emit the code for the procedure calls, and instructs the linker to look for these "missing pieces" in the other object modules.
What is usually done is to associate to each .cpp a .hpp (or .h if you are old-fashioned :) ) header which contains all the prototypes and declarations relative to its .cpp that should be accessible from the other modules. In this way, if A.cpp needs to call a function defined in B.cpp, it can simply include B.h.
A quick example may be:
A.hpp
#ifndef A_CPP_INCLUDED
#define A_CPP_INCLUDED
// ^^^ these are header guards, used to avoid multiple inclusions of the same header
// Declarations
// Notice that this does not define a global variable, it just says to the compiler "in some module there's a global named in this way, let me access it"
extern int AUselessGlobalVar;
int AddFive(int In);
#endif
A.cpp
#include "A.hpp" //it's useful that each .cpp includes its own .hpp, so it has all the prototypes already in place
// Actually define the var
int AUselessGlobalVar;
// Actually define the function
int AddFive(int In)
{
return In + 5;
}
Main.cpp
#include <iostream>
#include "A.h" // now it can access all the functions/vars declared in A.h
int main()
{
std::cin>>AUselessGlobalVar;
std::cout<<AddFive(AUselessGlobalVar);
return 0;
}
By the way, in this blog entry there's a nice description of the classical model for linking, which is quite related to what we're talking about.