std::invalid_义齿

31101 ワード

まずinvalid_について説明しますArgumentはクラス(class invalid_argument;)、その継承関係は次のとおりです.
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*文字列に変換され、はっきりした園友を望んで、答えを出して、ありがとうございます!