like comments said, “P1*” is a pointer to an object of type “P1”.
On the other hand ” * p1″ is an indirection (telling the compiler that it is an adress) on the content of the pointer p1;
P1* pp1; P1 p1;
returning *pp1 is like returning p1;
returning pp1 return the adress of the pointed object.
cf : C++ – *p vs &p vs p