我有一個簡短的問題。給定一個返回類的對象作爲結果的函數,如果沒有結果(說因爲索引超出範圍)應該返回什麼?我可以返回一個新的「空」對象,但我怎麼能指出沒有成功的計算?如何判斷沒有返回值的函數的結果?
我想有一個共同的方法。
我有一個簡短的問題。給定一個返回類的對象作爲結果的函數,如果沒有結果(說因爲索引超出範圍)應該返回什麼?我可以返回一個新的「空」對象,但我怎麼能指出沒有成功的計算?如何判斷沒有返回值的函數的結果?
我想有一個共同的方法。
當值與預期結果不匹配時,可以引發異常。
一個教程可以在http://www.cplusplus.com/doc/tutorial/exceptions
異常可與try和catch原則被發現。
程序「試圖」執行代碼。 如果發生意外事件,執行的代碼會「拋出」一個對象,變量或任何東西,這將被捕獲。 在catch語句中,您可以放置代碼如果發生意外事件應該發生的情況。
只需按照教程。
只需指出,通過僅引發std :: exception和子類,您可以爲自己和其他人節省很多痛苦,因爲它們提供了獲取含義完整錯誤字符串'what()'的單一方法。拋出純int類型的值必須是可以完成的最糟糕的事情。 – josefx 2013-03-05 18:39:59
但是拋出0xDEAD或0xBABE很有趣@josefx – Tschallacka 2013-03-06 07:37:48
C++中的常見方法是引發異常或使用一些包裝,如boost::optional
。
如果出現某種錯誤,應拋出異常,如果函數的有效用例返回空結果,那麼boost::optional
-approach更合適。想到的一個例子是SQL的NULL。在我們的代碼庫中,boost::optional
非常方便。
作爲一個方面說明,在一些或多或少的近期視頻中,我看到* Alexandrescu *提出了一個'Exceptional'類型(它是這種方式嗎?),最後是'boost :: optional',第二個選項不是它是一個空值,但是是一個例外,因此在概念上適用於錯誤情況(與普通的'boost :: optional'相反)。否則聲音推理+1。 – 2013-03-05 15:39:14
是的,也看到了,它叫'預計
按照vector::at方法的哲學,如果可能,拋出out_of_range
異常。
這取決於操作的語義。
如果錯誤發生後,你一定要拋出一個異常:
#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
}
您可以將枚舉與返回的對象類型配對。如果返回的枚舉值是特定值,則該對象有效,否則該對象處於無效狀態。
// 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
}
}
我可能只是拋出異常,而不是。
拋出異常http://www.cplusplus.com/doc/tutorial/exceptions/ – Tschallacka 2013-03-05 10:37:32
拋出異常? – PlasmaHH 2013-03-05 10:37:40
@MichaelDibbets。謝謝,我以前沒有用過。如果您將其寫成簡短的答案,我會將其標記爲已接受。 – danijar 2013-03-05 10:40:03