我應該如何撰寫一個有效的例外類來顯示可以通過在運行時之前修復源代碼錯誤來防止的錯誤?
這就是我選擇std::invalid_argument.
我的例外類(顯然不起作用):
class Foo_Exception : public std::invalid_argument
{
private:
std::string Exception_Msg;
public:
explicit Foo_Exception( const std::string& what_arg );
virtual const char* what( ) const throw( );
};
explicit Foo_Exception::Foo_Exception( const std::string& what_arg ) // how should I write this function???
{
Exception_Msg.reserve( 130000 );
Exception_Msg = "A string literal to be appended, ";
Exception_Msg = std::to_string( /* a constexpr int */ );
Exception_Msg = /* a char from a const unordered_set<char> */;
}
const char* Foo_Exception::what( ) const throw( )
{
return Exception_Msg.c_str( );
}
if拋出的塊Foo_Exception:
void setCharacter( const char& c )
{
if ( /* an invalid character (c) is passed to setCharacter */ )
{
try
{
const Foo_Exception foo_exc;
throw foo_exc;
}
catch( const Foo_Exception& e )
{
std::cerr << e.what( );
return;
}
}
/*
rest of the code
*/
}
int main( )
{
setCharacter( '-' ); // dash is not acceptable!
return 0;
}
如您所見,我需要連接Exception_Msg幾個子字串以形成完整的訊息。這些子字串不僅是字串文字,而且是來自 static 的constexpr ints 和chars std::unordered_set<char>。這就是我使用 std::string 的原因,因為它具有string::operator =易于使用的特性。不用說,我的目標是將堆分配減少到只有 1。
另一個非常重要的問題是我應該在哪里放置處理程式( try-catch )?在main()包裹setCharacter()里面還是把它留在里面setCharacter?
請制作一個與上述類似的良好且標準的自定義例外類。或者自己寫。提前致謝。
uj5u.com熱心網友回復:
而不是new char[]每次,為什么不擁有一個std::string資料成員?
class Foo_Exception : public std::exception /* ? */
{
std::string msg;
public:
Foo_Exception() {
msg.reserve( 130000 );
msg = "A string literal to be appended, ";
msg = "another string, ";
msg = "yet another one";
}
const char * what() const override { return msg.data(); }
/* other members ? */
}
或者您可以從std將字串作為構造引數的例外型別之一派生
class Foo_Exception : public std::runtime_error /* or logic_error */
{
public:
Foo_Exception() : runtime_error("A string literal to be appended, " "another string, " "yet another one") {}
/* other members ? */
}
但是,如果您只有字串文字,則可以將它們拆分為多個源代碼行,并且分配為零。
const char * what() const override {
return "A string literal to be appended, "
"another string, "
"yet another one";
}
uj5u.com熱心網友回復:
我根據其他人通過評論和回答收到的反饋解決了這個問題。所以我決定在這里為未來的讀者留下我自己的答案/解決方案。
下面可以看到我經過深思熟慮和研究后得出的結論。這個解決方案相當簡單和可讀。
這是例外類介面:
Foo_Exception.h
#include <exception>
class Foo_Exception : public std::invalid_argument
{
public:
explicit Foo_Exception( const std::string& what_arg );
};
這是它的實作:
Foo_Exception.cpp
#include "Foo_Exception.h"
Foo_Exception::Foo_Exception( const std::string& what_arg )
: std::invalid_argument( what_arg )
{
}
拋出的函式Foo_Exception:
Bar.cpp
#include "Bar.h"
#include "Foo_Exception.h"
void setCharacter( const char& c )
{
if ( /* an invalid character (c) is passed to setCharacter */ )
{
std::string exceptionMsg;
exceptionMsg.reserve( 130000 );
exceptionMsg = "A string literal to be appended, ";
exceptionMsg = std::to_string( /* a constexpr int */ );
exceptionMsg = /* a char from a const unordered_set<char> */;
throw Foo_Exception( exceptionMsg );
}
/*
rest of the code
*/
}
如何處理例外:
main.cpp
#include <iostream>
#include "Bar.h"
#include "Foo_Exception.h"
int main( )
{
try
{
setCharacter( '-' ); // The dash character is not valid! Throws Foo_Exception.
}
catch ( const Foo_Exception& e )
{
std::cerr << e.what( ) << '\n';
}
return 0;
}
變更概要:
請注意如何不需要
what()函式,因為編譯器隱式生成它,因為它Foo_Exception繼承自std::invalid_argument.此外,創建例外訊息的程序已從
Foo_Exception的建構式移至setCharacter實際拋出上述例外的函式體。這樣,Foo_Exception的 ctor 不負責創建訊息。相反,它是在拋出的函式體中創建的,然后傳遞給 ctorFoo_Exception以初始化新的例外物件。資料成員
std::string Exception_Msg也被洗掉了,Foo_Exception因為它不再需要了。最后,try-catch塊被移到,
main()以便它現在環繞setCharacter()并捕獲Foo_Exception它可能拋出的物件。
最后一句話: 非常感謝任何進一步改進我的答案的建議。非常感謝所有的反饋。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/362409.html
