Value equality is perfectly standardized in C++. Just use ==. If the
object doesn't support a sane concept of equality, then the code won't
compile.
Reference equality is more complex, because you can overload & to
do weird things, forcing you into very weird syntax. But if you have a
wrapper, the test looks like (boost::addressof(obj1) ==
boost::addressof(obj2)).
In Java, it's pretty much the same, except that reference equality is easier to do than value equality, which is bad.
Value equality is the equals method. You can compare anything and
everything with it, and if the implementation is stupid, you'll get an
exception. Objects that don't have a sane concept of equality fall back
to reference equality. Whether this is an improvement over the C++ way
is debateable.
Reference equality is ==. Except if the object in question is a
primitive, not a reference, in which case that's value equality.
Reference equality between primitives is not possible.
In other words, Java has a little inconsistency where C++ has none.
Now, it's been some time since I did C#, so the next block might not be exactly correct.
C# uses the Equals method for value equality. Unlike with Java, this
even works with primitives, simply because C# doesn't really have
primitives. It has value objects.
Reference equality is == in general, but this is not guaranteed,
because you can overload == to perform a different action, hopefully
value equivalence. Since this overrides the default == behaviour, you
need to explicitely cast to Object to guarantee using reference
equality, so the universal reference equality test is (((Object)obj1)
== ((Object)obj2)). However, due to value objects being boxed in such a
case, you still aren't guaranteed that you're really comparing the real
addresses, and I think there is a possibility of this comparison
failing in debug mode and succeeding in release, or similar unexpected
effects.
PHP, unlike the three above, is a dynamically and weakly typed
language, and got its OO features as an afterthough, indeed leading to
various WTFs. But I like it despite that.
First, you have to differ between PHP 4 and 5.
In PHP 4, there is no concept of reference equality. PHP4 only has the
concept of weak equality or equivalence, the == operator, and strong
equality or just equality, the === operator. Weak equality accepts
different values as equal, as long as they would be equivalent after a
typecast. Strong equality requires the values to be of the same type.
Comparing objects in PHP4 just uses element-wise comparison using the
operator supplied (so if you do obj1 == obj2, it does element-wise
comparison with ==; if you say obj1 === obj2, it uses ===.)
In PHP 5, this has changed. Now objects are handled by reference, not
by value. This means that while == is still element-wise comparison,
the === operator now checks reference equality. For all other types,
the behaviour is unchanged.
This actually makes sense in a weird way, but you have to accept a
rather twisted view of the programming model to see the sense in it.