Cha*_*rly 5 c++ getter setter exception
我的Getter/Setter方法在设置/返回之前检查该值.当值无效时,它们会抛出异常(BadArgumentException或IllegalStateException).这是必需的,因为我们使用无效值初始化所有成员 - 因此我们避免使用这些无效值(==在其他地方获取错误/段错误/异常).
好处是:
这似乎是非常不寻常的,因为大多数新团队成员首先抱怨它 - 即使他们在向我们解释之后同意我的意见.
问题:这是一种很好的编程风格吗?(即使它浪费了一点性能)
示例代码:
inline bool MyClass::HasGroupID const { return m_iGroupID != 0; }
int MyClass::GetGroupID() const
{
if( !HasGroupID() )
throw EPTIllegalStateException( "Cannot access uninitialized group ID!" );
return m_iGroupID;
} // END GetGroupID() const
void MyClass::SetGroupID( int iGroupID )
{
// negative IDs are allowed!
if( iGroupID != 0 )
throw EPTBadArgumentException( "GroupID must not be zero!", iGroupID );
m_iGroupID = iGroupID;
} // END SetGroupID( int )
Run Code Online (Sandbox Code Playgroud)
用法:
// in serialization
if( myObject.HasGroupID() )
rStream.writeAttribute( "groupid", GetGroupID() );
// in de-serialization
try {
// required attribute - throw exception if value is invalid
myObject.SetGroupID( rStream.GetIntegerAttribute( "groupid" );
} catch( EPTBadArgumentException& rException )
{
throw EPTBadXmlAttribute( fileName, rException );
}
Run Code Online (Sandbox Code Playgroud)
我认为这是常见的风格,而且它肯定是第一个想法中 getter/setter 的核心动机之一。但是,在您的特定示例中,我认为它们没有意义,而且我认为通常有更好的选择:
如果调用GetGroupID在HasGroupIDyield false 时引发异常,那么这是一个程序员错误 - 所以你可能应该使用assert. 事实上,为什么一开始就可以有一个没有组 ID 的对象?这听起来有点不雅的设计。
此外,如果只有非零 ID 有效,那么您应该尝试使用专用类型更早地强制执行此限制。这样,所有处理组 ID 的代码都可以确保 ID 有效(实际上,编译器会强制执行此操作!)并且您不可能忘记检查某个地方。考虑:
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; }
};
Run Code Online (Sandbox Code Playgroud)
使用这个,你可以写
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 )
Run Code Online (Sandbox Code Playgroud)
事实上,由于组 ID 现在是一种专用类型,您可以将函数重命名为 justSet并使用重载。所以,你必须MyClass::Set(UserID)和MyClass::Set(GroupID)等。