C++/CLI comparing two clr poiinters for equality

  • Thread starter Thread starter Edward Diener
  • Start date Start date
E

Edward Diener

Now that operator overloading allows to ref classes to be compared for
equality using == syntax, how does one compare the actual ref pointers (
^ ) for equality instead ?

As an example:

SomeRefObject ^ obj1(..initialized somehow);
SomeRefObject ^ obj2(..initialized somehow);

if (obj1 == obj2) // This compares the objects themselves for equality
in C++/CLI I assume. How do I compare the ref pointers themselves ( ^ )
for equality ?
 
Edward Diener said:
Now that operator overloading allows to ref classes to be compared for
equality using == syntax, how does one compare the actual ref pointers (
^ ) for equality instead ?

As an example:

SomeRefObject ^ obj1(..initialized somehow);
SomeRefObject ^ obj2(..initialized somehow);

if (obj1 == obj2) // This compares the objects themselves for equality in
C++/CLI I assume.

If SomeRefObject overwrites Equals, yes, otherwise no
How do I compare the ref pointers themselves ( ^ ) for equality ?

Object::ReferenceEquals(obj1, obj2)
 
Marcus said:
If SomeRefObject overwrites Equals, yes, otherwise no

So are you saying that operator overloading in C++/CLI for the ==
operator becomes equivalent to a ref class overloading the
Object::Equals method ?

Or is it that a ref class providing an overload for the Objecct::Equals
method now has that called when a C++/CLI programmer uses the == operator ?
Object::ReferenceEquals(obj1, obj2)

Thanks ! That will always works.

However operator overloading in C++/CLI has me a bit confused. Does
C++/CLI operator overloading relate to any .NET framework virtual member
functions that can be called from other .NET languages ? if so which
operator oveloads and which member functions.

In general I have found the documentation for clr class operator
overloading in MSDN for C++/CLI to be sparse to the extreme and
explaining almost nothing. There is a single topic page which I can find
which has no explanation how C++/CLI relates to .net member functions.
Have I missed a more profuse explanation of this somewhere in the MSDN
documentation for C++/CLI ?
 
Sorry, I was quite tired when I wrote this. That's why I confused some
things here. (At least I was the only one to find it out :-).)

By default, operator == works on reference types like
Object::ReferenceEquals, however types can override operator ==.
In C++/CLI and C#, operator == NEVER maps to Object::Equals.

Here is an app that shows how it works:

// eqt.cpp
// compile with "CL /clr:safe eqt.cpp"

using namespace System;

ref class ClassWithEquals
{
int i;
public:
ClassWithEquals(int i) : i(i) {}

virtual bool Equals(Object^ o) override
{
if (o == nullptr)
return false;

ClassWithEquals^ that = dynamic_cast<ClassWithEquals^>(o);
if (that == nullptr)
return false;

return this->i = that->i;
}
};

ref class ClassWithEqualityOperator
{
int i;
public:
ClassWithEqualityOperator(int i) : i(i) {}

bool operator==(ClassWithEqualityOperator^ that)
{
if (that == (Object^)nullptr)
return false;

return this->i == that->i;
}
};

int main()
{
ClassWithEquals^ cwe1 = gcnew ClassWithEquals(1);
ClassWithEquals^ cwe2 = gcnew ClassWithEquals(1);

if (cwe1 == cwe2)
Console::WriteLine("cwe1 == cwe2");

ClassWithEqualityOperator^ cwoe1 = gcnew ClassWithEqualityOperator(1);
ClassWithEqualityOperator^ cwoe2 = gcnew ClassWithEqualityOperator(1);

if (cwoe1 == cwoe2)
Console::WriteLine("cwoe1 == cwoe2");
}



If o
 
Marcus said:
Sorry, I was quite tired when I wrote this. That's why I confused some
things here. (At least I was the only one to find it out :-).)

By default, operator == works on reference types like
Object::ReferenceEquals, however types can override operator ==.
In C++/CLI and C#, operator == NEVER maps to Object::Equals.

Understood.

But I am gathering that if a class implements operator ==, then it
should also override Object::Equals to work in the same way in order to
be consistent.
Here is an app that shows how it works:

// eqt.cpp
// compile with "CL /clr:safe eqt.cpp"

using namespace System;

ref class ClassWithEquals
{
int i;
public:
ClassWithEquals(int i) : i(i) {}

virtual bool Equals(Object^ o) override
{
if (o == nullptr)
return false;

ClassWithEquals^ that = dynamic_cast<ClassWithEquals^>(o);
if (that == nullptr)
return false;

return this->i = that->i;
}
};

ref class ClassWithEqualityOperator
{
int i;
public:
ClassWithEqualityOperator(int i) : i(i) {}

bool operator==(ClassWithEqualityOperator^ that)
{
if (that == (Object^)nullptr)
return false;

return this->i == that->i;
}
};

int main()
{
ClassWithEquals^ cwe1 = gcnew ClassWithEquals(1);
ClassWithEquals^ cwe2 = gcnew ClassWithEquals(1);

if (cwe1 == cwe2)
Console::WriteLine("cwe1 == cwe2");

ClassWithEqualityOperator^ cwoe1 = gcnew ClassWithEqualityOperator(1);
ClassWithEqualityOperator^ cwoe2 = gcnew ClassWithEqualityOperator(1);

if (cwoe1 == cwoe2)
Console::WriteLine("cwoe1 == cwoe2");
}

Thanks for the example.
 
Edward Diener said:
Understood.

But I am gathering that if a class implements operator ==, then it should
also override Object::Equals to work in the same way in order to be
consistent.

This argument sounds plausible to me. If you follow this argument, then you
should also overide Object::GetHashCode, because some container classes in
the FCL expect the following behavior:

( obj1->Equals(obj2) ) => ( obj1->GetHashCode() ==
obj2->GetHashCode() )

Marcus
 
Back
Top