当对象是指针时重载 == 和 !==
Overloading == and !== when object is a pointer
我是编写运算符的新手(在本例中为 ==
和 !=
)。我做了一些研究,到目前为止想出了:
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);
}
当我尝试使用这些运算符时,令我感到惊讶的是:
if (pEntry != sEvent)
{
AfxMessageBox(_T("The special event information has changed"));
}
它不喜欢 pEntry
作为指针。最后我这样做了:
if (*pEntry != sEvent)
{
AfxMessageBox(_T("The special event information has changed"));
}
- 为什么这首先是一个问题?我这么问是因为如果这是一个标准函数,那么对象是不是指针都没有关系。
- 迎合这种情况的正确方法是什么?
例如:
object->Function(value)
object.Function(value)
Function
当它是/不是指针时,它可以被对象使用。那么为什么不用 operator
?
Function
can be used both by the object when it is / is not a pointer.
事实上,不,它不能。在像 object->Function(value)
这样的 statement/expression 中,->
(成员访问)和 ()
(函数调用)运算符具有 same precedence 和 left-to-right结合性。因此,首先应用 ->
并自动解除对指针的引用。因此,效果与 (*object).Function(value)
相同 – 而 Function
是 still 在 object 上被调用,而不是在指针上。
So why not with an operator
?
调用operator
函数的语法是(或者可以)相当不同:因为它被定义为运算符,您可以使用运算符标记(在两个操作数之间)调用它,而不是使用显式函数调用。但是,你 必须 传递对象,因为这就是操作数的定义。
但是,如果您真的想要,您 可以 仍然使用显式 function-call 语法调用运算符覆盖;并且,在这种情况下,您可以在指针上使用 ->
;像这样(其中 operator==
实际上是函数的 'name'):
if (!pEntry->operator==(sEvent))
{
AfxMessageBox(_T("The special event information has changed"));
}
然而,这似乎是一项艰巨的工作,而您的 *pEntry != sEvent
实际上是 'correct' 使用覆盖的方式。
PS:作为奖励,如果您使用的编译器支持 C++20(或更高版本)标准,您可以在 structures/classes 中添加 "defaulted" operator==
,这将节省您显式比较每个单独的数据成员的时间:
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"
};
我是编写运算符的新手(在本例中为 ==
和 !=
)。我做了一些研究,到目前为止想出了:
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);
}
当我尝试使用这些运算符时,令我感到惊讶的是:
if (pEntry != sEvent)
{
AfxMessageBox(_T("The special event information has changed"));
}
它不喜欢 pEntry
作为指针。最后我这样做了:
if (*pEntry != sEvent)
{
AfxMessageBox(_T("The special event information has changed"));
}
- 为什么这首先是一个问题?我这么问是因为如果这是一个标准函数,那么对象是不是指针都没有关系。
- 迎合这种情况的正确方法是什么?
例如:
object->Function(value)
object.Function(value)
Function
当它是/不是指针时,它可以被对象使用。那么为什么不用 operator
?
Function
can be used both by the object when it is / is not a pointer.
事实上,不,它不能。在像 object->Function(value)
这样的 statement/expression 中,->
(成员访问)和 ()
(函数调用)运算符具有 same precedence 和 left-to-right结合性。因此,首先应用 ->
并自动解除对指针的引用。因此,效果与 (*object).Function(value)
相同 – 而 Function
是 still 在 object 上被调用,而不是在指针上。
So why not with an
operator
?
调用operator
函数的语法是(或者可以)相当不同:因为它被定义为运算符,您可以使用运算符标记(在两个操作数之间)调用它,而不是使用显式函数调用。但是,你 必须 传递对象,因为这就是操作数的定义。
但是,如果您真的想要,您 可以 仍然使用显式 function-call 语法调用运算符覆盖;并且,在这种情况下,您可以在指针上使用 ->
;像这样(其中 operator==
实际上是函数的 'name'):
if (!pEntry->operator==(sEvent))
{
AfxMessageBox(_T("The special event information has changed"));
}
然而,这似乎是一项艰巨的工作,而您的 *pEntry != sEvent
实际上是 'correct' 使用覆盖的方式。
PS:作为奖励,如果您使用的编译器支持 C++20(或更高版本)标准,您可以在 structures/classes 中添加 "defaulted" operator==
,这将节省您显式比较每个单独的数据成员的时间:
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"
};