我有一个简短的问题。给定一个返回类对象作为结果的函数,如果没有结果(比如因为索引超出范围),我应该返回什么?我可以返回一个新的“空”对象,但我如何指出没有成功计算?
我想有一个共同的方法。
我有一个简短的问题。给定一个返回类对象作为结果的函数,如果没有结果(比如因为索引超出范围),我应该返回什么?我可以返回一个新的“空”对象,但我如何指出没有成功计算?
我想有一个共同的方法。
C++ 中的常用方法是抛出异常或使用一些包装器,如boost::optional
.
如果是某种错误,则应抛出异常,如果它是boost::optional
函数的有效用例以返回空结果,则 - 方法更合适。想到的一个例子是 SQL 的 NULL。boost::optional
在我们的代码库中非常方便。
这取决于操作的语义是什么。
如果发生错误,您绝对应该抛出异常:
#include <stdexcept> // Necessary for standard exceptions
X foo()
{
...
if (/* something goes wrong... */)
{
// There may be a more appropriate exception class. You could
// also derive your own exception class from std::exception...
throw std::logic_error("Whatever!");
}
...
}
...
try
{
X x = foo();
// Work with x...
}
catch (std::logic_error const& e) // Catch what is appropriate...
{
std::cout << e.what();
}
如果返回无值不表示错误情况,则可以使用Boost.Optional。或者,如果您可以创建一个类型为“空”的对象X
,您可以考虑返回一对,其第二个成员是一个bool
标志,该标志告诉第一个成员是否为有效对象,如下所示:
std::pair<X, bool> foo();
...
bool valid;
X x;
std::tie(x, valid) = foo();
if (valid)
{
// Use x...
}
如果我们谈论错误的情况,抛出异常是正确的解决方案。
#include<exception>
Object * GenerateObject(int i)
{
if (i < 0)
throw std::out_of_range("i");
return new Object(i);
}
int main(int argc, char * argv[])
{
try
{
Object * obj = GenerateObject(-1);
// Succeeded
return 0;
}
catch (std::exception & e)
{
// Failed, exiting with error value
return 1;
}
}
如果允许空值,您可以为此类指定特定值,例如。
class Rectangle
{
private:
int left, top, width, height;
public:
Rectangle(l, t, w, h)
{
left = l;
top = t;
width = w;
height = h;
}
public static Rectangle empty;
}
Rectangle Rectangle::empty = Rectangle(0, 0, -1, -1);
// ...
Rectangle DoSth(int i)
{
// i < 0 is NOT considered an error here
if (i < 0)
return Rectangle::empty;
// Further processing
}
如果可能,按照vector::at方法的理念抛出out_of_range
异常。
当值与预期结果不匹配时,您可以抛出异常。
可以在http://www.cplusplus.com/doc/tutorial/exceptions找到教程
异常适用于 try and catch 原则。
程序“尝试”执行代码。如果发生意外情况,执行的代码会“抛出”一个对象、变量或其他任何东西,这将被捕获。在 catch 语句中,您可以放置代码,如果发生意外情况应该发生什么。
只需按照教程。
您可以将枚举与返回的对象类型配对。如果返回的枚举为某个值,则该对象有效,否则该对象处于无效状态。
// This is a working C++11 example.
#include <utility>
#include <memory>
enum result
{
ok,
out_of_range,
some_other_error
};
class object
{
public:
object() {}
};
typedef std::shared_ptr< object > object_ptr;
typedef std::pair< result, object_ptr > return_type;
return_type some_function( int index )
{
if ( index > 5 )
{
return return_type{ result::out_of_range, nullptr };
}
return return_type{ result::ok, object_ptr{ new object() } };
}
int main()
{
return_type res = some_function( 10 );
if ( res.first == result::ok )
{
// Do something with res.second
}
else
{
// Handle the error
}
}
我可能会抛出一个异常。