std::invalid_义齿
31101 ワード
まずinvalid_について説明しますArgumentはクラス(class invalid_argument;)、その継承関係は次のとおりです.
exception-------->logic_error--------->invalid_argument
invalid_Argumentプロトタイプは
実行結果:
では、上記の例は最も簡単な応用です.invalid_Argumentはその名の通り無効なパラメータを指し、これはパラメータが無効であるかどうかを検査するために適用されるべきであり、一般的にパラメータが特定の関数およびクラスに使用されることを検査すると、クラスのメンバー変数に値を付与するか、または関数パラメータに値を付与する場合に、それらに付与された値が有効であるかどうかを検査する.たとえば、3つのメンバー変数name,age,heightを持つクラス(people)がある場合、人の年齢は0~150歳であることがわかります(ps:プログラマーに対して0~75と直接定義できる場合).身長は0~300 cm、名前の長さは20を超えません.これらの範囲を超えている場合は、無効なデータとみなすことができます.このクラスは次のように定義できます.
実行結果は次のとおりです.
上のプログラムは無効なデータを入力すると、エラーが出力されます.しかし、それだけでは十分ではありません.無効なパラメータがどのファイルとどの行にあるか、またはどの関数にあるかを特定することはできません.印刷エラー時にこれらの情報を出力して位置決め問題を信じると便利です.では、私たちはエラーメッセージを報告するときに、これらの情報も添付すると明らかになります.
実行結果は次のとおりです.
注意:
(1)上の#define TOSTRING(x)#xでintタイプをconst char*タイプに変換できます.
(2) __FILE__はconst char*タイプであり、#define TOSTRING(x)変換後のタイプはconst char*タイプであり、コンパイラがgunである場合に取得される関数名は_PRETTY_FUNCTION__const char*タイプでもあります.
が表示されますLINE__行番号は表示されません.理由コンパイラは直接_LINE__「_LINE_」に変換この文字列ですが、ここではどうやって解決しますか?筆者はいろいろな方法を試してみたが、最終的に見つけた.私たちは1回で、正常な現実になることができる.次のコード
実行結果は次のとおりです.
中の原理については、なぜ2回で_LINE__表示された数字は、例えば(71)ではなくconst char*"71"に変換され、"_LINE_"const char*文字列に変換され、はっきりした園友を望んで、答えを出して、ありがとうございます!
exception-------->logic_error--------->invalid_argument
invalid_Argumentプロトタイプは
1 class invalid_argument:public logic_error {
2 public:
3 explicit invalid_argument (const string& what_arg);
4 };
stdexceptヘッダファイルでstdネーミングスペース内にあります.次に例を挙げて使用します 1 #include <iostream>
2 #include <stdexcept>
3
4 int main(int argc,char ** argv)
5 {
6 try
7 {
8 bool errorArgument;
9 errorArgument=true;
10 if(errorArgument)
11 {
12 throw std::invalid_argument("occur error!");
13 }
14 }
15 catch(std::invalid_argument &ia)
16 {
17 //what() invalid_argument exception
18 std::cerr<<" Invalid_argument "<< ia.what()<<std::endl;
19 }
20
21 return 0;
22 }
実行結果:
Invalid_argument occur error!
では、上記の例は最も簡単な応用です.invalid_Argumentはその名の通り無効なパラメータを指し、これはパラメータが無効であるかどうかを検査するために適用されるべきであり、一般的にパラメータが特定の関数およびクラスに使用されることを検査すると、クラスのメンバー変数に値を付与するか、または関数パラメータに値を付与する場合に、それらに付与された値が有効であるかどうかを検査する.たとえば、3つのメンバー変数name,age,heightを持つクラス(people)がある場合、人の年齢は0~150歳であることがわかります(ps:プログラマーに対して0~75と直接定義できる場合).身長は0~300 cm、名前の長さは20を超えません.これらの範囲を超えている場合は、無効なデータとみなすことができます.このクラスは次のように定義できます.
1 #include <stdexcept>
2 #include <iostream>
3 #include <string>
4
5 class People
6 {
7 public:
8 People(const std::string& n,const int& a,const int& h)
9 :name(n),age(a),height(h)
10 {}
11
12 inline void set(const std::string& n,const int& a,const int& h)
13 {
14 if(!valid(n,a,h))
15 {
16 throw std::invalid_argument("People's argument is error");
17 }
18 name = n;
19 age = a;
20 height = h;
21 }
22
23 inline bool valid(const std::string& n, const int& a, const int& h)
24 {
25 return ( n.length() == 0 ||n.length() > 20 )&& a >= 0 && a< 150 && h > 0 && h < 300 ;
26 }
27 private:
28 std::string name;
29 int age;
30 int height;
31
32 };
33
34 int main(int argc, char** argv)
35 {
36 People p("Li San", 20 , 170);
37 try
38 {
39 p.set("Li San" , 20 ,1700);
40 }
41 catch (std::invalid_argument & ia)
42 {
43 std::cerr << "Error: " << ia.what() << std::endl;
44 }
45 return 0;
46 }
実行結果は次のとおりです.
Error: People's argument is error
上のプログラムは無効なデータを入力すると、エラーが出力されます.しかし、それだけでは十分ではありません.無効なパラメータがどのファイルとどの行にあるか、またはどの関数にあるかを特定することはできません.印刷エラー時にこれらの情報を出力して位置決め問題を信じると便利です.では、私たちはエラーメッセージを報告するときに、これらの情報も添付すると明らかになります.
1 #include <stdexcept>
2 #include <iostream>
3 #include <string>
4 #define TOSTRING(x) #x
5
6 //class ErrorInfo
7 //{
8 // public:
9 // ErrorInfo(const std::string& f,const std::string& l,const std::string& fun)
10 // : file(f), line(l), func(fun)
11 // {}
12 //
13 // inline const std::string getFile() const
14 // {
15 // return this->file;
16 // }
17 //
18 // inline const std::string getLine() const
19 // {
20 // return this->line;
21 // }
22 //
23 // inline const std::string getFunc() const
24 // {
25 // return this->func;
26 // }
27 //
28 // private:
29 // const std::string file;
30 // const std::string line;
31 // const std::string func;
32 //};
33
34 class ErrorInfo
35 {
36 public:
37 ErrorInfo(const char * f, const char * l, const char * fun)
38 :file(f), line(l), func(fun)
39 {}
40
41 inline std::string getFile() const
42 {
43 return this->file;
44 }
45
46 inline std::string getLine() const
47 {
48 return this->line;
49 }
50
51 inline std::string getFunc() const
52 {
53 return this->func;
54 }
55 private:
56 const char* file;
57 const char* line;
58 const char* func;
59 };
60
61 std::string operator +(const std::string & str, const ErrorInfo& ei)
62 {
63 std::string strTemp(ei.getFile() + ":" + ei.getLine() + ":" + ei.getFunc());
64 strTemp +=str;
65 return strTemp;
66 //return str::string(ei.getFile() + ":" + ei.getLine() + ":" + ei.getFunc() += str );
67 }
68
69 class InvalidPeople:public std::invalid_argument
70 {
71 public:
72 InvalidPeople(ErrorInfo & ei)
73 : std::invalid_argument( "Invalid People " + ei )
74 {}
75 ~InvalidPeople() throw()
76 {}
77 };
78
79 class People
80 {
81 public:
82 People(const std::string& n,const int& a,const int& h)
83 :name(n),age(a),height(h)
84 {}
85
86 inline void set(const std::string& n,const int& a,const int& h)
87 {
88 if(!valid(n,a,h))
89 {
90 ErrorInfo ei(__FILE__,TOSTRING(__LINE__),__PRETTY_FUNCTION__);
91 // ErrorInfo ei(__FILE__,#__LINE__,__PRETTY_FUNCTION__);
92 throw InvalidPeople(ei);
93 // throw InvalidPeople(ErrorInfo(__FILE__,TOSTRING(__LINE__),__PRETTY_FUNCTION__));
94 }
95 name = n;
96 age = a;
97 height = h;
98 }
99
100 inline bool valid(const std::string& n, const int& a, const int& h)
101 {
102 return ( n.length() == 0 ||n.length() > 20 )&& a >= 0 && a< 150 && h > 0 && h < 300 ;
103 }
104 private:
105 std::string name;
106 int age;
107 int height;
108
109 };
110
111 int main(int argc, char** argv)
112 {
113 People p("Li San", 20 , 170);
114 try
115 {
116 p.set("Li San" , 20 ,1700);
117 }
118 catch (std::invalid_argument & ia)
119 {
120 std::cerr << "Error: " << ia.what() << std::endl;
121 }
122 return 0;
123 }
実行結果は次のとおりです.
TestError: invalid_a.cpp:__LINE__:void People::set(const std::string&, const int&, const int&)Invalid People
注意:
(1)上の#define TOSTRING(x)#xでintタイプをconst char*タイプに変換できます.
(2) __FILE__はconst char*タイプであり、#define TOSTRING(x)変換後のタイプはconst char*タイプであり、コンパイラがgunである場合に取得される関数名は_PRETTY_FUNCTION__const char*タイプでもあります.
が表示されますLINE__行番号は表示されません.理由コンパイラは直接_LINE__「_LINE_」に変換この文字列ですが、ここではどうやって解決しますか?筆者はいろいろな方法を試してみたが、最終的に見つけた.私たちは1回で、正常な現実になることができる.次のコード
1 #include <stdexcept>
2 #include <iostream>
3 #include <string>
4 #define TTOSTRING(x) #x
5 #define TOSTRING(x) TTOSTRING(x)
6 ...
7 ...
8 //
実行結果は次のとおりです.
TestError: invalid_a.cpp:91:void People::set(const std::string&, const int&, const int&)Invalid People
中の原理については、なぜ2回で_LINE__表示された数字は、例えば(71)ではなくconst char*"71"に変換され、"_LINE_"const char*文字列に変換され、はっきりした園友を望んで、答えを出して、ありがとうございます!