First and third options are good - which one to choose depends on your intentions. I wouldn't use second option - it doesn't reveal it's intention.
When you use first method, you clearly state, that addition will modify object. When a programmer sees:
Foo f1, f2;
f1.add(&f2);
He/she already knows, that f1 can/will be modified by this call.
When you use third method, you state, that none of passed objects will be modified, so when programmer sees:
Foo f1, f2;
Foo *result;
result = Foo.add(&f1, &f2);
He/she knows, that f1 and f2 will NOT be modified (and you should use options that language gives you to enforce this).
As I wrote - choice between first and third method depends on your intentions. If you want to treat Foo as value object - that means that you can trust that once you set it's fields they will remain that way no matter where you pass your object, use third method. If you want to treat Foo as object which state can and will change, and you agree that passing a Foo object to a method can change it's state - use first option.
However, when you use second option - programmer will not know whether you modify first, second, both or neither of arguments. Don't use this option.