爲什麼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. GCC 4.9 std :: string const char *
- 2. 如何在std :: string中存儲const char *?
- 3. 如何在std :: string中存儲const char * []?
- 4. 不能將'std :: string {aka std :: basic_string}'轉換爲'const char *'參數'1'到'int system(const char *)
- 5. 哪一個使用const char []或const std :: string?
- 6. 從「std :: istringstream」初始化「const std :: string」
- 7. 運算符std :: string()const?
- 8. C++ const std :: string賦值
- 9. 不能超載的std :: string常量和函數爲const char *
- 10. 數據去變換爲const char *時的std :: string
- 11. 從內部使用靜態std :: string的函數返回const char *是否安全?
- 12. 我應該返回gsl :: span <const T>而不是const std :: vector <T>&
- 13. C++傳遞字符串而不是const std :: string&?
- 14. 返回const char的函數*
- 15. 當使用const std :: string&作爲方法參數類型時,處理nullptr const char *的正確方法是什麼?
- 16. shared_from_this()返回std :: shared_ptr <const X>,而不是std :: shared_ptr <X>
- 17. 爲什麼std :: set <> :: find返回一個const?
- 18. 爲什麼不是std :: string是std :: vector的專門化?
- 19. 轉換爲std :: string並在一行中獲取const char *
- 20. 字符串自動轉換爲const char *到的std :: string
- 21. 轉換std :: string爲const char *和函數調用
- 22. 爲什麼不strlen的(..)預計爲const char * const的海峽,而不是爲const char *
- 23. 不存在從「std :: string」到「const char *」的合適轉換函數
- 24. 從'const std :: __ 1 :: basic_string <char>到'std :: __ 1 :: basic_string <char> *'
- 25. gcc 4.9.1不符合標準? (std :: runtime_error)
- 26. 在std :: string :: assign(std :: string const&)中的分段錯誤
- 27. 將std :: string.assign(const char *)或op =(with const char *)創建一個char *的副本?
- 28. NSString爲char(不是const char)
- 29. 如何返回一個const std :: vector <Object * const>?
- 30. std :: upper_bound在const成員函數中返回const迭代器
-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