C++ Primer学习笔记2--c++异常处理和函数

本文介绍了C++中的异常处理机制,包括throw表达式、try块及标准库异常类等,并详细探讨了不同类型的异常及其应用场景。此外,还讲解了函数的定义、参数传递方式、内联函数以及函数重载等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   异常处理

 

 1.throw表达式

 

 throw runtime_error("Data must refer to same ISBN");

 

 

 2.try

 

 while (cin >> item1 >> item2) {

 

 try {

        

        if (!item1.same_isbn(item2))

        throw runtime_error("Data must refer to same ISBN");

 

 } catch (runtime_error err) {

 

        cout << err.what()

                << "\nTry Again? Enter y or n" << endl;

        char c;

        cin >> c;

        if (cin && c == 'n')

        break;     // break out of the while loop

 } }

 3.标准库异常类

 

 1.<exception> exception

 2.<stdexcept>

 exception 最常见的问题。

 

 

 runtime_error 运行时错误:仅在运行时才能检测到问题

 

 

 range_error 运行时错误:生成的结果超出了有意义的值域范围

 

 

 overflow_error 运行时错误:计算上溢

 

 

 underflow_error 运行时错误:计算下溢

 

 

 logic_error 逻辑错误:可在运行前检测到问题

 

 

 domain_error 逻辑错误:参数的结果值不存在

 

 

 invalid_argument 逻辑错误:不合适的参数

 

 

 length_error 逻辑错误:试图生成一个超出该类型最大长度的对象

 

 

 out_of_range 逻辑错误:使用一个超出有效范围的值

 

 

 3.<new>bad_alloc

 

 4.<type_info> bad_cast

 

 预处理进行调试

 

 #ifndef  NDEBUG 

 ........

 #endif

 ........

 

 

 

 <cassert>  assert()断言

 

 

 -----------------------------

 函数

 

 返回值类型 函数名(形参列表){/函数体/}  

    int    main (int argc, const char * argv[]){..}

 

 函数必须指定返回类型

 形参可以为空,但不能省略,可以不写或用void代替

 传递的实参会检查类型,必须符合或经转换后可以符合

 

 参数传递

每次调用函数时,都会重新创建该函数所有的形参,此时所传递的实参将会 初始化对应的形参。

 形参的初始化与变量的初始化一样:如果形参具有非引用类型, 则复制实参的值,

 如果形参为引用类型,则它只是实参的别名。

 

 非引用形参:

 普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初 始化形参时,

 函数并没有访问调用所传递的实参本身,因此不会修改实参的值。

 

 指针形参

 函数的形参是指针,此时将复制实参指针,事实上被复制的指针只影响对指针的赋值。如果 函数形参是非 const 类型的指针,则函数可通过指针实现赋值,修改指针所指 向对象的值:

 

 void reset(int *ip)

 {

    *ip = 0; // changes the value of the object to which ip points 

    ip = 0; // changes only the local value of ip; the argument is unchanged

 }

 调用 reset ,实参依然保持原来的值,但它所指向的对象的值将变为 0:

 

 如果保护指针指向的值,则形参需定义为指向 const 对象的指针:

 void use_ptr(const int *p)

 {

 

 }

 

 

 注:指针形参是指向 const 类型还是非 const 类型,将影响函数调用所使用的 实参。我们既可以用 int* 也可以用 const int* 类型的实参调用 use_ptr ;但仅能将 int* 类型的实参传递给 reset 函数。这个差别来源于指针的初 始化规则。可以将指向 const 对象的指针初始化为指向非 const 对象,但不可以让指向非 const 对象的指针向 const 对象。

 

 

 复制实参的局限性 复制实参并不是在所有的情况下都适合,不适宜复制实参的情况包括:

 • 当需要在函数中修改实参的值时。

 • 当需要以大型对象作为实参传递时。对实际的应用而言,复制对象所付出

 的时间和存储空间代价往往过在。

 • 当没有办法实现对象的复制时。

 

 对于上述几种情况,有效的解决办法是将形参定义为引用或指针类型。

 

 例如定义一个函数交换两个参数的值,就需要用引用形参

 

 

 利用 const 引用避免复制(如果使用引用形参的唯一目的是避免复制实参,则应将形参定 义为 const 引用。)

 bool isShorter(const string &s1, const string &s2)

 {

 return s1.size() < s2.size();

 }

 因为形参是引用,所以不复 制实参。又因为形参是 const 引用,所以 isShorter 函数不能使用该引用来修 改实参。

 

 

 如果函数具有普通的非 const 引用形参,调用这样的函数时,传递一个右值( 2.3.1 ) 或具有需要转换的类型的对象同样是不允许的:

 

 

 应该将不修改相应实参的形参定义为 const 引用。

 

 

 传递指向指针的引用

 

 vector 和其他容器类型的形参

 C++ 程序员倾向于通过传递指向容器中需要 处理的元素的迭代器来传递容器:

 

 void print(vector<int>::const_iterator beg , vector<int>::const_iterator end)

 {

 while (beg != end) {

 cout << *beg++;

 if (beg != end) cout << " "; // no space after last element }

 cout << endl;

 }

 这个函数将输出从 beg 指向的元素开始到 end 指向的元素(不含)为止的 范围内所有的元素


 

 内联函数inline

  inline 函数放入头文件

 

 

 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。

 

 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const。所以 const 关键字对成员函数的行为作了更加明确的限定:有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const 修饰的成员函数,对数据成员则是可读可写的。


 

 出现在相同作用域中的两个函数,如果具有相同的名字而形参表不同,则称为重

 载函数。编译器将根据所传 递的实参类型来判断调用的是哪个函数。

 如果两个函数声明的返回类型和形参表完全匹配,则将第二个函数声明视为第一 个的重复声明。如果两个函数的形参表完全相同,但返回类型不同,则第二个声 明是错误的:

 Record lookup(const Account&);

 bool lookup(const Account&); // error: only return type is different

 函数不能仅仅基于不同的返回类型而实现重载。

 

 

 指向函数的指针

 bool (*pf)(const string &, const string &);

 这个语句将 pf 声明为指向函数的指针,它所指向的函数带有两个 const string& 类型的形参和 bool 类型的返回值。

 

 

  typedef 简化函数指针的定义,cmpFcn是一种指向函数的指针

 typedef bool (*cmpFcn)(const string &, const string &)

 通过指针调用函数

 cmpFcn pf = lengthCompare;

 lengthCompare("hi", "bye");


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值