Confusion über C ++ - Zeiger und Referenzthema

Was ist der Unterschied zwischen den folgenden Parameterübergabemechanismen in C ++?

void foo(int &x) 
void foo(int *x)
void foo(int **x)
void foo(int *&x)

Ich möchte wissen, in welchem Fall der Parameter als Wert oder als Referenz übergeben wird.