如何判断返回值没有函数的结果?

时间:2013-03-05 10:36:00

标签: c++ function error-handling coding-style return-type

我有一个简短的问题。给定一个返回类对象的函数作为结果,如果没有结果,应该返回什么(比如因为索引超出范围)?我可以返回一个新的“空”对象,但我怎么能指出没有成功的计算?

我想有一个共同的方法。

6 个答案:

答案 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
    }
}

我可能只会抛出异常。