Confusão sobre ponteiro C ++ e tópico de referência

Qual é a diferença entre o seguinte parâmetro passando mecanismos em C ++?

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

Gostaria de saber em que caso o parâmetro está sendo passado por valor ou por referência.