Я думаю, что это общий стиль, и это, безусловно, одна из основных мотиваций для геттеров / сеттеров в первой идее. Однако, в вашем конкретном примере, я не думаю, что они имеют смысл, и я думаю, что в целом часто есть лучшие альтернативы:
Если вызов GetGroupID
вызывает исключение, если HasGroupID
выдает false, то это ошибка программиста - поэтому вам, вероятно, следует использовать assert
. На самом деле, почему вообще возможно иметь объект без идентификатора группы? Это звучит как слегка не элегантный дизайн.
Кроме того, если допустимы только ненулевые идентификаторы, вам следует попытаться применить это ограничение еще раньше, используя выделенный тип. Таким образом, весь код, имеющий дело с идентификаторами групп, может быть уверен, что идентификаторы действительны (на самом деле, компилятор обеспечивает это!), И вы не можете забыть проверить в каком-то месте. Рассмотрим:
class GroupID {
public:
explicit GroupID( int id ) : m_id( id ) {
if ( m_id == 0 ) {
throw EPTBadArgumentException( "GroupID must not be zero!", m_id );
}
}
// You may want to allow implicit conversion or rather use an explicit getter
operator int() const { return m_id; }
};
Используя это, вы можете просто написать
void MyClass::SetGroupID( GroupID id )
{
// No error checking needed; we *know* it's valid, because it's a GroupID!
// We can also use a less verbose variable name without losing readability
// because the type name reveals the semantics.
m_iGroupID = id;
} // END SetGroupID( int )
Фактически, поскольку идентификаторы групп теперь являются выделенным типом, вы можете переименовать свою функцию просто на Set
и использовать перегрузки. Итак, у вас есть MyClass::Set(UserID)
и MyClass::Set(GroupID)
и т. Д.