c++ std::invalid_argument應(yīng)用
更新時(shí)間:2013年01月02日 16:30:03 作者:
想研究std::invalid_argument的朋友可以參考下
首先說明invalid_argument是一個(gè)類(class invalid_argument;),它的繼承關(guān)系如下
exception-------->logic_error--------->invalid_argument
invalid_argument原型是
class invalid_argument:public logic_error {
public:
explicit invalid_argument (const string& what_arg);
};
它在stdexcept頭文件中,在std命名空間內(nèi)。下面舉一個(gè)例子來使用它
#include <iostream>
#include <stdexcept>
int main(int argc,char ** argv)
{
try
{
bool errorArgument;
errorArgument=true;
if(errorArgument)
{
throw std::invalid_argument("occur error!");
}
}
catch(std::invalid_argument &ia)
{
//what()為invalid_argument繼承exception類的函數(shù)
std::cerr<<" Invalid_argument "<< ia.what()<<std::endl;
}
return 0;
}
運(yùn)行結(jié)果為:
Invalid_argument occur error!那么上面的例子是一個(gè)最簡(jiǎn)單的應(yīng)用了。invalid_argument顧名思義指無(wú)效參數(shù),這個(gè)應(yīng)該應(yīng)用在檢查參數(shù)是否是無(wú)效的,一般檢查參數(shù)用于特定的函數(shù)以及類,那么就應(yīng)該是給類的成員變量賦值或者函數(shù)參數(shù)賦值時(shí),檢查其賦給它們的值是否有效,例如有一個(gè)類(people,有三個(gè)成員變量name,age,height)那么我們知道人的年齡在0~150歲之間(ps:如果對(duì)于程序員可以直接定義為0~75)。身高的話0~300cm,名字的長(zhǎng)度不會(huì)超過20。如果都超過這些范圍,就可以認(rèn)定是無(wú)效數(shù)據(jù)。那么這個(gè)類可以如下定義:
#include <stdexcept>
#include <iostream>
#include <string>
class People
{
public:
People(const std::string& n,const int& a,const int& h)
:name(n),age(a),height(h)
{}
inline void set(const std::string& n,const int& a,const int& h)
{
if(!valid(n,a,h))
{
throw std::invalid_argument("People's argument is error");
}
name = n;
age = a;
height = h;
}
inline bool valid(const std::string& n, const int& a, const int& h)
{
return ( n.length() == 0 ||n.length() > 20 )&& a >= 0 && a< 150 && h > 0 && h < 300 ;
}
private:
std::string name;
int age;
int height;
};
int main(int argc, char** argv)
{
People p("Li San", 20 , 170);
try
{
p.set("Li San" , 20 ,1700);
}
catch (std::invalid_argument & ia)
{
std::cerr << "Error: " << ia.what() << std::endl;
}
return 0;
}
其運(yùn)行結(jié)果為:
Error: People's argument is error上面程序只要輸入無(wú)效數(shù)據(jù),就會(huì)輸出錯(cuò)誤。但是僅僅這樣是不夠的,我們還無(wú)法定位無(wú)效參數(shù)在哪個(gè)文件與哪個(gè)一行或者在哪個(gè)函數(shù)中,如果在打印錯(cuò)誤的時(shí)候連這些信息一并輸出相信定位問題就方便多了。那么我們?cè)趫?bào)出錯(cuò)誤信息的時(shí)候連這些信息也附加上就明確多了。
#include <stdexcept>
#include <iostream>
#include <string>
#define TOSTRING(x) #x
//class ErrorInfo
//{
// public:
// ErrorInfo(const std::string& f,const std::string& l,const std::string& fun)
// : file(f), line(l), func(fun)
// {}
//
// inline const std::string getFile() const
// {
// return this->file;
// }
//
// inline const std::string getLine() const
// {
// return this->line;
// }
//
// inline const std::string getFunc() const
// {
// return this->func;
// }
//
// private:
// const std::string file;
// const std::string line;
// const std::string func;
//};
class ErrorInfo
{
public:
ErrorInfo(const char * f, const char * l, const char * fun)
:file(f), line(l), func(fun)
{}
inline std::string getFile() const
{
return this->file;
}
inline std::string getLine() const
{
return this->line;
}
inline std::string getFunc() const
{
return this->func;
}
private:
const char* file;
const char* line;
const char* func;
};
std::string operator +(const std::string & str, const ErrorInfo& ei)
{
std::string strTemp(ei.getFile() + ":" + ei.getLine() + ":" + ei.getFunc());
strTemp +=str;
return strTemp;
//return str::string(ei.getFile() + ":" + ei.getLine() + ":" + ei.getFunc() += str );
}
class InvalidPeople:public std::invalid_argument
{
public:
InvalidPeople(ErrorInfo & ei)
: std::invalid_argument( "Invalid People " + ei )
{}
~InvalidPeople() throw()
{}
};
class People
{
public:
People(const std::string& n,const int& a,const int& h)
:name(n),age(a),height(h)
{}
inline void set(const std::string& n,const int& a,const int& h)
{
if(!valid(n,a,h))
{
ErrorInfo ei(__FILE__,TOSTRING(__LINE__),__PRETTY_FUNCTION__);
// ErrorInfo ei(__FILE__,#__LINE__,__PRETTY_FUNCTION__);
throw InvalidPeople(ei);
// throw InvalidPeople(ErrorInfo(__FILE__,TOSTRING(__LINE__),__PRETTY_FUNCTION__));
}
name = n;
age = a;
height = h;
}
inline bool valid(const std::string& n, const int& a, const int& h)
{
return ( n.length() == 0 ||n.length() > 20 )&& a >= 0 && a< 150 && h > 0 && h < 300 ;
}
private:
std::string name;
int age;
int height;
};
int main(int argc, char** argv)
{
People p("Li San", 20 , 170);
try
{
p.set("Li San" , 20 ,1700);
}
catch (std::invalid_argument & ia)
{
std::cerr << "Error: " << ia.what() << std::endl;
}
return 0;
}
其運(yùn)行結(jié)果為:
TestError: invalid_a.cpp:__LINE__:void People::set(const std::string&, const int&, const int&)Invalid People注意:
(1)上面#define TOSTRING(x) #x就可以將int類型轉(zhuǎn)換為const char *類型。
(2) __FILE__是const char*類型,并且通過#define TOSTRING(x)轉(zhuǎn)換后的類型為const char*類型,編譯器是gun那么獲取所在的函數(shù)名稱就是__PRETTY_FUNCTION__也是const char*類型。
可以看到__LINE__并沒有顯示出行號(hào),這里原因編譯器直接將__LINE__其轉(zhuǎn)換為"__LINE__"這個(gè)字符串了那么這里如何解決呢?筆者試過好多方法,最終找出來了,我們可以在#define一次,就可以正?,F(xiàn)實(shí)了。如下代碼
#include <stdexcept>
#include <iostream>
#include <string>
#define TTOSTRING(x) #x
#define TOSTRING(x) TTOSTRING(x)
...
...
//后面代碼與上面一樣
其運(yùn)行結(jié)果為:
TestError: invalid_a.cpp:91:void People::set(const std::string&, const int&, const int&)Invalid People
至于里面原理,為什么兩次就能夠?qū)_LINE__表示的數(shù)字例如(71)轉(zhuǎn)換成const char* “71”,而不是轉(zhuǎn)換成“__LINE__"const char*字符串,希望清楚的園友,給出答案,謝謝!
exception-------->logic_error--------->invalid_argument
invalid_argument原型是
復(fù)制代碼 代碼如下:
class invalid_argument:public logic_error {
public:
explicit invalid_argument (const string& what_arg);
};
它在stdexcept頭文件中,在std命名空間內(nèi)。下面舉一個(gè)例子來使用它
復(fù)制代碼 代碼如下:
#include <iostream>
#include <stdexcept>
int main(int argc,char ** argv)
{
try
{
bool errorArgument;
errorArgument=true;
if(errorArgument)
{
throw std::invalid_argument("occur error!");
}
}
catch(std::invalid_argument &ia)
{
//what()為invalid_argument繼承exception類的函數(shù)
std::cerr<<" Invalid_argument "<< ia.what()<<std::endl;
}
return 0;
}
運(yùn)行結(jié)果為:
Invalid_argument occur error!那么上面的例子是一個(gè)最簡(jiǎn)單的應(yīng)用了。invalid_argument顧名思義指無(wú)效參數(shù),這個(gè)應(yīng)該應(yīng)用在檢查參數(shù)是否是無(wú)效的,一般檢查參數(shù)用于特定的函數(shù)以及類,那么就應(yīng)該是給類的成員變量賦值或者函數(shù)參數(shù)賦值時(shí),檢查其賦給它們的值是否有效,例如有一個(gè)類(people,有三個(gè)成員變量name,age,height)那么我們知道人的年齡在0~150歲之間(ps:如果對(duì)于程序員可以直接定義為0~75)。身高的話0~300cm,名字的長(zhǎng)度不會(huì)超過20。如果都超過這些范圍,就可以認(rèn)定是無(wú)效數(shù)據(jù)。那么這個(gè)類可以如下定義:
復(fù)制代碼 代碼如下:
#include <stdexcept>
#include <iostream>
#include <string>
class People
{
public:
People(const std::string& n,const int& a,const int& h)
:name(n),age(a),height(h)
{}
inline void set(const std::string& n,const int& a,const int& h)
{
if(!valid(n,a,h))
{
throw std::invalid_argument("People's argument is error");
}
name = n;
age = a;
height = h;
}
inline bool valid(const std::string& n, const int& a, const int& h)
{
return ( n.length() == 0 ||n.length() > 20 )&& a >= 0 && a< 150 && h > 0 && h < 300 ;
}
private:
std::string name;
int age;
int height;
};
int main(int argc, char** argv)
{
People p("Li San", 20 , 170);
try
{
p.set("Li San" , 20 ,1700);
}
catch (std::invalid_argument & ia)
{
std::cerr << "Error: " << ia.what() << std::endl;
}
return 0;
}
其運(yùn)行結(jié)果為:
Error: People's argument is error上面程序只要輸入無(wú)效數(shù)據(jù),就會(huì)輸出錯(cuò)誤。但是僅僅這樣是不夠的,我們還無(wú)法定位無(wú)效參數(shù)在哪個(gè)文件與哪個(gè)一行或者在哪個(gè)函數(shù)中,如果在打印錯(cuò)誤的時(shí)候連這些信息一并輸出相信定位問題就方便多了。那么我們?cè)趫?bào)出錯(cuò)誤信息的時(shí)候連這些信息也附加上就明確多了。
復(fù)制代碼 代碼如下:
#include <stdexcept>
#include <iostream>
#include <string>
#define TOSTRING(x) #x
//class ErrorInfo
//{
// public:
// ErrorInfo(const std::string& f,const std::string& l,const std::string& fun)
// : file(f), line(l), func(fun)
// {}
//
// inline const std::string getFile() const
// {
// return this->file;
// }
//
// inline const std::string getLine() const
// {
// return this->line;
// }
//
// inline const std::string getFunc() const
// {
// return this->func;
// }
//
// private:
// const std::string file;
// const std::string line;
// const std::string func;
//};
class ErrorInfo
{
public:
ErrorInfo(const char * f, const char * l, const char * fun)
:file(f), line(l), func(fun)
{}
inline std::string getFile() const
{
return this->file;
}
inline std::string getLine() const
{
return this->line;
}
inline std::string getFunc() const
{
return this->func;
}
private:
const char* file;
const char* line;
const char* func;
};
std::string operator +(const std::string & str, const ErrorInfo& ei)
{
std::string strTemp(ei.getFile() + ":" + ei.getLine() + ":" + ei.getFunc());
strTemp +=str;
return strTemp;
//return str::string(ei.getFile() + ":" + ei.getLine() + ":" + ei.getFunc() += str );
}
class InvalidPeople:public std::invalid_argument
{
public:
InvalidPeople(ErrorInfo & ei)
: std::invalid_argument( "Invalid People " + ei )
{}
~InvalidPeople() throw()
{}
};
class People
{
public:
People(const std::string& n,const int& a,const int& h)
:name(n),age(a),height(h)
{}
inline void set(const std::string& n,const int& a,const int& h)
{
if(!valid(n,a,h))
{
ErrorInfo ei(__FILE__,TOSTRING(__LINE__),__PRETTY_FUNCTION__);
// ErrorInfo ei(__FILE__,#__LINE__,__PRETTY_FUNCTION__);
throw InvalidPeople(ei);
// throw InvalidPeople(ErrorInfo(__FILE__,TOSTRING(__LINE__),__PRETTY_FUNCTION__));
}
name = n;
age = a;
height = h;
}
inline bool valid(const std::string& n, const int& a, const int& h)
{
return ( n.length() == 0 ||n.length() > 20 )&& a >= 0 && a< 150 && h > 0 && h < 300 ;
}
private:
std::string name;
int age;
int height;
};
int main(int argc, char** argv)
{
People p("Li San", 20 , 170);
try
{
p.set("Li San" , 20 ,1700);
}
catch (std::invalid_argument & ia)
{
std::cerr << "Error: " << ia.what() << std::endl;
}
return 0;
}
其運(yùn)行結(jié)果為:
TestError: invalid_a.cpp:__LINE__:void People::set(const std::string&, const int&, const int&)Invalid People注意:
(1)上面#define TOSTRING(x) #x就可以將int類型轉(zhuǎn)換為const char *類型。
(2) __FILE__是const char*類型,并且通過#define TOSTRING(x)轉(zhuǎn)換后的類型為const char*類型,編譯器是gun那么獲取所在的函數(shù)名稱就是__PRETTY_FUNCTION__也是const char*類型。
可以看到__LINE__并沒有顯示出行號(hào),這里原因編譯器直接將__LINE__其轉(zhuǎn)換為"__LINE__"這個(gè)字符串了那么這里如何解決呢?筆者試過好多方法,最終找出來了,我們可以在#define一次,就可以正?,F(xiàn)實(shí)了。如下代碼
復(fù)制代碼 代碼如下:
#include <stdexcept>
#include <iostream>
#include <string>
#define TTOSTRING(x) #x
#define TOSTRING(x) TTOSTRING(x)
...
...
//后面代碼與上面一樣
其運(yùn)行結(jié)果為:
TestError: invalid_a.cpp:91:void People::set(const std::string&, const int&, const int&)Invalid People
至于里面原理,為什么兩次就能夠?qū)_LINE__表示的數(shù)字例如(71)轉(zhuǎn)換成const char* “71”,而不是轉(zhuǎn)換成“__LINE__"const char*字符串,希望清楚的園友,給出答案,謝謝!
相關(guān)文章
c語(yǔ)言float類型小數(shù)點(diǎn)后位數(shù)
在本篇文章里小編給大家整理了關(guān)于c語(yǔ)言float類型小數(shù)點(diǎn)后面有幾位的相關(guān)知識(shí)點(diǎn),需要的朋友們可以學(xué)習(xí)下。2020-02-02C++插件化 NDD源碼的插件機(jī)制實(shí)現(xiàn)解析
這篇文章主要介紹了C++插件化 NDD源碼的插件機(jī)制實(shí)現(xiàn)解析,這里再介紹推薦下優(yōu)秀的國(guó)產(chǎn)軟件開源項(xiàng)目?NDD(notepad--),一個(gè)支持windows/linux/mac的文本編輯器,目標(biāo)是要國(guó)產(chǎn)替換同類軟件,需要的朋友可以參考下2023-03-03VS2022連接sqlserver數(shù)據(jù)庫(kù)教程
本文主要介紹了VS2022連接sqlserver數(shù)據(jù)庫(kù)教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07C++數(shù)據(jù)精度問題(對(duì)浮點(diǎn)數(shù)保存指定位小數(shù))
這篇文章主要介紹了對(duì)浮點(diǎn)數(shù)保存指定位小數(shù)。比如, 1.123456. 要保存1位小數(shù),,調(diào)用方法后, 保存的結(jié)果為: 1.1。 再比如,1.98765, 保存2位小數(shù)的結(jié)果為: 2.00,需要的朋友可以參考下2017-08-08C語(yǔ)言超詳細(xì)講解隊(duì)列的實(shí)現(xiàn)及代碼
隊(duì)列(Queue)與棧一樣,是一種線性存儲(chǔ)結(jié)構(gòu),它具有如下特點(diǎn):隊(duì)列中的數(shù)據(jù)元素遵循“先進(jìn)先出”(First?In?First?Out)的原則,簡(jiǎn)稱FIFO結(jié)構(gòu)。在隊(duì)尾添加元素,在隊(duì)頭刪除元素2022-04-04C語(yǔ)言實(shí)現(xiàn)餐飲管理與點(diǎn)餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)餐飲管理與點(diǎn)餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01