爲什麼std::runtime_error::what()
返回的是const char*
而不是std::string const&
? 在許多情況下,對嵌入字符串的引用的直接返回將會很方便,並且可以避免一些開銷。那麼不返回的理由是什麼?首先是對內部字符串的const引用,而不提供重載函數?我想它與字符串ctor一起能夠拋出異常,但我沒有看到返回字符串引用的風險。爲什麼std :: runtime_error :: what()返回const char *而不是std :: string const&
回答
std::runtime_error
繼承自std::exception
它定義了virtual const char* what() const throw();
,所以最簡單的回答是它是函數的重載,並且您可以確定任何標準異常都以這種方式定義它。它可能(取決於實現)返回std::string
,但它會與標準庫的其餘部分不一致。
我認爲what()
返回const char*
的原因是,您可以避免任何可能失敗的操作(特別是可能會引發異常)。考慮下面的代碼,不應該在下面的代碼的std::string
分配可能會失敗,失敗
virtual const char* what() const throw() {
return "An error has occured";
}
然而,拋出一個異常:
std::string what() const throw() {
return std::string("An error has occured");
}
如果字符串的構造扔在這裏,應用程序將無論如何,最有可能崩潰,因爲該函數指定throw()
。
在異常中使用std::string
引入了分配不可能的內存的需要(注意,std::bad_alloc
也從std::exception
繼承)。
不一定是嵌入std::string
。成員函數what
是虛擬的,即它被設計爲被覆蓋。忽略它的主要原因是以其他方式提供字符串,而不是通過std::runtime_error
(無論機制是什麼,最可能是存儲的std::string
)使用的機制。
好點,有人可能會說char是更一般的。我看了一下在內部使用一個字符串的gcc stl實現''class runtime_error:public exception {string} _M_msg;''並且有點被誤導了。 – Martin 2012-07-21 17:47:44
雖然runtime_error確實將std :: string作爲參數,所以它可以保留它並按照您的建議返回它,what()方法從std :: exception繼承,所以更一般。
由於堆棧展開,拋出異常的開銷很可能已經很高,因此您不應該擔心這種額外的額外開銷。
你很對,開銷顯然可以忽略不計。我更感興趣的原因是爲什麼不採取直接的方式作爲你的繼承點 – Martin 2012-07-21 17:55:17
- 1. std :: string gets(char *)而不是(const char *)
- 2. 「std :: string const」與「const std :: string」
- 3. GCC 4.9 std :: string const char *
- 4. 函數重載爲const char *,const char(&)[N]和std :: string
- 5. 爲什麼std :: string的const訪問器返回一個引用?
- 6. C++比較爲const char *到的std :: string
- 7. 無法將'std :: string'轉換爲'const char *
- 8. 返回char數組而不是const char *
- 9. C++,爲什麼使用const std :: string&parameterName?
- 10. 轉換爲const char **的爲std :: vector的<std::string>
- 11. 爲什麼cStringUsingEncoding:返回const char *而不是char *?
- 12. 不能從'const char *'轉換爲'char *'爲std :: string :: c_str
- 13. 如何在std :: string中存儲const char * []?
- 14. 如何在std :: string中存儲const char *?
- 15. std :: string與靜態const的char數組
- 16. 爲什麼GCC接受std :: strrchr()返回的值從'const char *'轉換爲'char *'?
- 17. 從函數返回const char *的正確方法,例如覆蓋std :: exception :: what()
- 18. 從std :: string中提取const char而不復制?
- 19. 哪一個使用const char []或const std :: string?
- 20. 從const char * +長度構造一個const std :: string便宜嗎?
- 21. 不能將'std :: string {aka std :: basic_string}'轉換爲'const char *'參數'1'到'int system(const char *)
- 22. 從「std :: istringstream」初始化「const std :: string」
- 23. 運算符std :: string()const?
- 24. C++ const std :: string賦值
- 25. 不能超載的std :: string常量和函數爲const char *
- 26. 無法將'const char *'轉換爲'std :: istream *
- 27. 數據去變換爲const char *時的std :: string
- 28. 「const std :: string&msg」什麼,如何以及爲什麼? C++
- 29. 我應該返回gsl :: span <const T>而不是const std :: vector <T>&
- 30. 從內部使用靜態std :: string的函數返回const char *是否安全?
-1截至本評論時,答案中的代碼將不會編譯,即它不正確。如果存在'std :: string',則不會保證措辭「可能返回'std :: string'」,即不正確。拋出「什麼」會引入「一次拋出兩個異常」的說法是不正確的:在處理程序中調用了什麼。一次拋出兩個異常的註釋在技術上是不正確的:在堆棧展開期間,可以執行try塊,允許嵌套異常拋出。但這似乎只是模糊的措辭。 – 2012-07-21 18:18:18
好的,我修正了代碼,並重新說明了拋出第二個異常的說明,以使它更清楚(我希望)。正如Alf所說,異常可以在try塊中拋出。 – stativ 2012-07-22 07:22:22
現在,代碼將被編譯,但如果使用會導致未定義的行爲(它會返回一個指向臨時的指針)。三個不正確的技術索賠仍然存在。這個答案仍然沒有回答OP的問題,「爲什麼」,即有很多不正確的說法,還有無意義的UB代碼,而且沒有答案。 – 2012-07-22 12:07:35