服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - c++ std::invalid_argument应用

c++ std::invalid_argument应用

2020-11-15 22:15C++教程网 C/C++

想研究std::invalid_argument的朋友可以参考下

首先说明invalid_argument是一个类(class invalid_argument;),它的继承关系如下

exception-------->logic_error--------->invalid_argument

invalid_argument原型是

复制代码 代码如下:


class invalid_argument:public logic_error {
public:
explicit invalid_argument (const string& what_arg);
};


它在stdexcept头文件中,在std命名空间内。下面举一个例子来使用它

复制代码 代码如下:


#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类的函数
std::cerr<<" Invalid_argument "<< ia.what()<<std::endl;
}

return 0;
}


运行结果为:

Invalid_argument occur error!那么上面的例子是一个最简单的应用了。invalid_argument顾名思义指无效参数,这个应该应用在检查参数是否是无效的,一般检查参数用于特定的函数以及类,那么就应该是给类的成员变量赋值或者函数参数赋值时,检查其赋给它们的值是否有效,例如有一个类(people,有三个成员变量name,age,height)那么我们知道人的年龄在0~150岁之间(ps:如果对于程序员可以直接定义为0~75)。身高的话0~300cm,名字的长度不会超过20。如果都超过这些范围,就可以认定是无效数据。那么这个类可以如下定义:

复制代码 代码如下:


#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;
}


其运行结果为:

Error: People's argument is error上面程序只要输入无效数据,就会输出错误。但是仅仅这样是不够的,我们还无法定位无效参数在哪个文件与哪个一行或者在哪个函数中,如果在打印错误的时候连这些信息一并输出相信定位问题就方便多了。那么我们在报出错误信息的时候连这些信息也附加上就明确多了。

复制代码 代码如下:


#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;
}


其运行结果为:

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__"这个字符串了那么这里如何解决呢?笔者试过好多方法,最终找出来了,我们可以在#define一次,就可以正常现实了。如下代码

复制代码 代码如下:


#include <stdexcept>
#include <iostream>
#include <string>
#define TTOSTRING(x) #x
#define TOSTRING(x) TTOSTRING(x)
...
...
//后面代码与上面一样


其运行结果为:

TestError: invalid_a.cpp:91:void People::set(const std::string&, const int&, const int&)Invalid People
至于里面原理,为什么两次就能够将__LINE__表示的数字例如(71)转换成const char* “71”,而不是转换成“__LINE__"const char*字符串,希望清楚的园友,给出答案,谢谢!

延伸 · 阅读

精彩推荐
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16