我有一个简短的问题。给定一个返回类对象的函数作为结果,如果没有结果,应该返回什么(比如因为索引超出范围)?我可以返回一个新的“空”对象,但我怎么能指出没有成功的计算?
我想有一个共同的方法。
答案 0 :(得分:13)
C ++中的常见方法是抛出异常或使用像boost::optional
这样的包装器。
如果是某种错误,则应抛出异常,boost::optional
- 方法更合适,如果它是函数返回空结果的有效用例。想到的一个例子是SQL的NULL。 boost::optional
在我们的代码库中非常方便。
答案 1 :(得分:3)
如果可能的话,遵循vector::at方法的哲学抛出out_of_range
异常。
答案 2 :(得分:3)
这取决于操作的语义。
如果发生错误,您肯定应该抛出异常:
#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...
}
答案 3 :(得分:3)
如果我们在谈论错误的情况,抛出异常是正确的解决方案。
#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
}
答案 4 :(得分:2)
当值与预期结果不匹配时,您可以抛出异常。
可以在http://www.cplusplus.com/doc/tutorial/exceptions
找到教程异常适用于try和catch原则。
程序“尝试”执行代码。 如果出现意外情况,执行的代码会“抛出”一个对象,变量或其他东西,这将被捕获。 在catch语句中,您可以放置代码,如果意外发生了应该发生的事情。
只需按照教程。
答案 5 :(得分:0)
您可以将枚举与要返回的对象类型配对。如果返回的枚举是某个值,则该对象有效,否则该对象处于无效状态。
// 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
}
}
我可能只会抛出异常。