Home > Blockchain >  Overloading == and !== when object is a pointer
Overloading == and !== when object is a pointer

Time:02-17

I am new to writing operators (in this case == and !=). I have done a bit of research and so far came up with:

bool operator==(const SPECIAL_EVENT_S &rsEvent)
{
    bool bSame = false;

    if (rsEvent.datEvent == m_datSpecialEvent &&
        rsEvent.strEvent == m_strNotes &&
        rsEvent.strLocation == m_strLocation &&
        rsEvent.datEventStartTime == m_datEventStartTime &&
        rsEvent.datEventFinishTime == m_datEventFinishTime &&
        gsl::narrow<bool>(rsEvent.bEventAllDay) == m_bEventAllDay &&
        gsl::narrow<bool>(rsEvent.bSetReminder) == m_bSetReminder &&
        rsEvent.iReminderUnitType == m_iReminderUnitType &&
        rsEvent.iReminderInterval == m_iReminderInterval &&
        rsEvent.iImageWidthPercent == m_wImageWidthPercent &&
        rsEvent.strImagePath == m_strImagePath &&
        rsEvent.strTextBeforeImage == m_strTextBeforeImage &&
        rsEvent.strTextAfterImage == m_strTextAfterImage &&
        rsEvent.eType == m_eVideoconfType &&
        rsEvent.sBSSTI == m_sBSSTI)
    {
        // The fundamental information is unchanged
        bSame = true;
    }

    // Now compare the MWB Event Type
    if (bSame)
    {
        switch (rsEvent.eMWBEventType)
        {
        case EventTypeMWB::MWBBethelSpeakerServiceTalk:
            return m_bSpecialEventBethelServiceTalk;
        case EventTypeMWB::MWBVideoconferenceAssembly:
            return m_bSpecialEventVideoconf && m_eVideoconfType == VideoConferenceEventType::Live;
        case EventTypeMWB::MWBVideoconferenceConvention:
            return m_bSpecialEventVideoconf && m_eVideoconfType == VideoConferenceEventType::Recorded;
        case EventTypeMWB::MWBSpecialEvent:
            return m_bSpecialEvent;
        case EventTypeMWB::MWBMemorial:
            return m_bEventMemorial;
        case EventTypeMWB::MWBCircuitOverseerMeeting:
            return m_bCircuitVisit || m_bCircuitVisitGroup;
        case EventTypeMWB::MWBMeeting:
            return !m_bNoMeeting;
        default:
            bSame = false;
        }
    }

    return bSame;
}
bool operator!=(const SPECIAL_EVENT_S& rsEvent)
{
    return !(rsEvent == *this);
}

What surprised me what when I then tried to use these operators:

if (pEntry != sEvent)
{
    AfxMessageBox(_T("The special event information has changed"));
}

It does not like pEntry being a pointer. In the end I did this:

if (*pEntry != sEvent)
{
    AfxMessageBox(_T("The special event information has changed"));
}
  1. Why was this an issue in the first place? I ask that because if this was a standard function it would not matter if the object was a pointer or not.
  2. What is the correct way to cater for this scenario?

For example:

  • object->Function(value)
  • object.Function(value)

Function can be used both by the object when it is / is not a pointer. So why not with an operator?

CodePudding user response:

Function can be used both by the object when it is / is not a pointer.

Actually, no it can't. In a statement/expression like object->Function(value) the -> (member access) and () (function call) operators have the same precedence and left-to-right associativity. So, the -> is applied first and that automatically dereferences the pointer. So, the effect is the same as (*object).Function(value) – and Function is still being called on an object, rather than on a pointer.

So why not with an operator?

The syntax for calling an operator function is (or can be) rather different: because it is defined as an operator, you can call it using the operator token (between the two operands) rather than by using an explicit function call. But then, you have to pass objects, as that's what the operands are defined to be.

However, should you really want to, you can still call an operator override using explicit function-call syntax; and, in that case, you can use the -> on a pointer; like this (where operator== is effectively the 'name' of the function):

if (!pEntry->operator==(sEvent))
{
    AfxMessageBox(_T("The special event information has changed"));
}

However, this seems like a lot of hard work and your *pEntry != sEvent is actually the 'correct' way to use the override.


PS: As bonus, if you're using a compiler that supports the C 20 (or later) Standard, you can add a "defaulted" operator== to your structures/classes, which would save you explicitly comparing each individual data member:

struct foo {
    int a;
    double b;
    bool operator==(const foo&) const = default; // Compares "a" and "b"
};

struct bar {
    foo f;
    int c;
    int d;
    bool operator==(const bar&) const = default; // Compares "c", "d" and "f"
};
  • Related