为我不恰当的术语道歉.
我有一段代码,如果条目不存在,则返回NULL指针:
ObjectType * MyClass::FindObjectType( const char * objectTypeName )
{
if ( objectTypeMap.find( objectTypeName ) == objectTypeMap.end() )
{
Msg( "\n[C++ ERROR] No object type: %s", objectTypeName );
return NULL;
}
else
return &objectTypeMap[ objectTypeName ];
}
Run Code Online (Sandbox Code Playgroud)
我想做同样的事情,但这次返回一个对象而不是一个指针.以下代码没有给我任何编译器错误(这让我感到惊讶):
ObjectType MyClass::FindObjectType( const char * objectTypeName )
{
if ( objectTypeMap.find( objectTypeName ) == objectTypeMap.end() )
{
Msg( "\n[C++ ERROR] No object type: %s", objectTypeName );
}
else
return objectTypeMap[ objectTypeName ];
}
Run Code Online (Sandbox Code Playgroud)
使用指针我可以检查是否找不到这样的条目:
if ( FindObjectType( objectType ) == NULL )
//Do something
Run Code Online (Sandbox Code Playgroud)
如何对返回的对象执行等效检查?
Oli*_*rth 12
对象没有语言级别的等价物.
一种选择是创建一个"sentinel"对象,保证比较不等于任何"真实"对象,并返回:
class ObjectType {
public:
static const ObjectType null;
bool operator==(const ObjectType &rhs) const { /* need an appropriate comparison test */ }
...
};
ObjectType ObjectType::null(/* something unique */);
...
ObjectType foo(const char *objectTypeName) {
if (cond) {
return objectTypeMap[objectTypeName];
} else {
return ObjectType::null;
}
}
...
if (foo(objectType) == ObjectType::null) {
std::cout << "Returned the null object\n";
}
Run Code Online (Sandbox Code Playgroud)
以下代码没有给出错误,因为标准非常保守。
有些代码结构极其复杂,编译器无法知道是否到达函数末尾。因此,标准说编译器不必证明函数正确返回一个值......
然而,标准确实规定,如果函数正常结束(无例外)而没有返回值,则调用未定义行为(即,任何事情都可能发生,可能是崩溃)。因此,大多数编译器都会对这种情况发出警告,对于 gcc 和 Clang,您可以使用-Wreturn.
现在,空值或哨兵值的原则并不新鲜,空指针只是其中的一种体现(其中之一)。
如果您的对象可为空没有意义(很少这样做,但可以是一种权宜之计),那么您有两种选择:
throw发出错误信号的异常boost::optional<ObjectType>返回一个可能为 null 的包装类(例如)在这种情况下,由于预计Find可能找不到任何东西,所以我一般建议后者。
用法很简单:
boost::optional<ObjectType> MyClass::FindObjectType(char const* objectTypeName )
{
if ( objectTypeMap.find( objectTypeName ) == objectTypeMap.end() ) {
// do not print anything, it is up to the caller to decide what to do
return boost::none;
}
return objectTypeMap[ objectTypeName ];
}
Run Code Online (Sandbox Code Playgroud)
然后调用者写道:
int main(int argc, char* argv[]) {
if (boost::optional<ObjectType> o = MyClass::FindObject(argv[1])) {
o->foo();
return 0;
}
Msg( "\n[C++ ERROR] No object type: %s", argv[1]);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7037 次 |
| 最近记录: |