5

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

我想有一个共同的方法。

4

6 回答 6

13

C++ 中的常用方法是抛出异常或使用一些包装器,如boost::optional.

如果是某种错误,则应抛出异常,如果它是boost::optional函数的有效用例以返回空结果,则 - 方法更合适。想到的一个例子是 SQL 的 NULL。boost::optional在我们的代码库中非常方便。

于 2013-03-05T10:38:36.500 回答
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...
}
于 2013-03-05T10:40:46.357 回答
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
}
于 2013-03-05T10:40:54.230 回答
3

如果可能,按照vector::at方法的理念抛出out_of_range异常。

于 2013-03-05T10:38:38.170 回答
2

当值与预期结果不匹配时,您可以抛出异常。

可以在http://www.cplusplus.com/doc/tutorial/exceptions找到教程

异常适用于 try and catch 原则。

程序“尝试”执行代码。如果发生意外情况,执行的代码会“抛出”一个对象、变量或其他任何东西,这将被捕获。在 catch 语句中,您可以放置​​代码,如果发生意外情况应该发生什么。

只需按照教程。

于 2013-03-05T10:44:36.823 回答
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
    }
}

我可能会抛出一个异常。

于 2013-03-05T22:07:23.753 回答