c++编码规范与知识笔记——(四)异常

老规矩,先上一段编码规范。

1. variable names
 

for (int i = 1; i < 5; i++){

  for (int j = 1; j <= n1; j++){

    if (n1 % j == 0)

      g = j;

  }

}

 

 

25. Iterator variables should be called i, j, k etc. Variables named j, k etc. should be used for nested loops only

25. 迭代变量应使用i,j,k等字母。j,k等应仅用于嵌套循环中

 

14. Variables with a large scope should have long names, variables with a small scope can have short names [1].

14. 大作用域的变量应使用长名字,小作用域的变量应使用短名字

 

 

2. Group the Header Files
 

41. Include statements should be sorted and grouped. Sorted by their hierarchical position in the system

with low level files included first. Leave an empty line between groups of include statements.

41. 包含语句应排序并分组。排序时,按其在系统中的层次位置,较低层的包含语句在前。用空行分隔分组的包含语句

#include <fstream>

#include <iomanip>

#include <qt/qbutton.h>

#include <qt/qtextfield.h>

#include "com/company/ui/PropertiesDialog.h"

#include "com/company/ui/MainWindow.h"

包含文件的路径中,一定不要使用绝对路径

 


42. Include statements must be located at the top of a file only.

42. 包含语句必须放在文件的顶部

将包含语句放到源代码的其它位置,可能会导致预期之外的编译副作用
下面进入异常处理的学习
1. Example Snippet for try-throw-catch (踹扔抓的代码块示例)
try {
  Code to try;
  throw an exception    (1) with a throw statement
                        (2) or from function;
  More code to try;
}
catch (type e) {
  Code to process the exception;
}

例如: TWO way to deal with " divide an integer by 0 " (两种处理被0除的方法)
 
(1)     use if statement (使用if语句)
(2)     use exception handling (使用异常处理)

int main() {
  // Read two intergers
  cout << "Enter two integers: ";
  int number1, number2;
  cin >> number1 >> number2;
  try {
    if (number2 == 0)
      throw number1;
    cout << number1 << " / " << number2 <<
            " is "  << (number1 / number2) << endl;
  }
  catch (int e) {
    cout << "Exception: an integer " << e <<
            " cannot be divided by zero" << endl;
  }
  cout << "Execution continues ..." << endl;
}








2. Exception-Handling Advantages (异常处理机制的优点)
Advantages: bring the exceptional information in callee to the caller 
(优点:可将异常信息从被调函数带回给主调函数)
//用异常处理
int quotient(int number1, 
             int number2) {
  if (number2 == 0) 
    throw number1; 
  return number1 / number2;
} 

int main() {
  try {
    int x = quotient(1, 0);
  } catch (int) {
    std::cout << "除数为0!";
  }
}

若不用异常处理:
quotient()如何告诉 main() "number2 有问题"? 
(1) 用返回值?——难以确定规则
if(number2 == 0) return x; //x应该是0还是1?

(2) 用指针/引用类型的参数?——函数形式过于“丑陋”
int quotient(int n1, int n2, int &s){
    if(n2 == 0) s=-1; //求商,函数要3个参数?
}

(3) 如果采用 f(g(h(quotient(x,y)))); 怎样将错误从quotient() 传到 f()?




3. Exception Match and Exception Classes
 异常匹配与异常类

 

3-1. catch: Match with Exception Type (catch: 按异常类型匹配)

catch ( ExceptionType& parameter ) { /* 处理异常 */ }try{}中所抛异常类型与catch()的参数类型(ExceptionType)匹配,则进入catch块

若对异常对象的内容不感兴趣,可省略catch参数,只保留类型
void f1() { throw 100; }
void f2() { for (int i = 1; i <= 100; i++) new int[70000000]; }



try { f1(); }
catch (int) { //仅有类型
  cout << "Error" << endl;
}
try { f2(); } 
catch (bad_alloc) {
  cout << "new failed" << endl;
}




try { f1(); }
catch (int& e) { //类型+参数
  cout << e << endl;
}


try { f2(); } 
catch (bad_alloc &e) {
  cout << "Exception: " << e.what() << endl;
}


3-2. Why Exception Class (为何要使用异常类)
不使用异常类,则捕获的异常所能传递的信息量很少
try {
  // ...
}
catch (int e) {
  //do something with e
}

使用异常类,则可以在抛出异常时传递很多信息,在捕获异常时接收这些信息去进行我们想要的处理
class Beautiful {
  string name;
  string hometown;
  int    salary;
  string misdoing;
// ………… 
}
try {
  // ...
}
catch (Beautiful object) {
  //do something with object
}







4. Build-in Exception Classes
 内建异常类
 
4-1 Base Class of Exception in Standard Library(标准库中的异常基类) 

1.1. #include <exception>


1.2. class exception;
exception(); // 构造函数
virtual const char* what(); //返回解释性字符串 
what()返回的指针指向拥有解释信息的空终止字符串的指针。该指针保证在获取它的异常对象被销毁前,
或在调用该异常对象的非静态成员函数前合法

1.3. exception 是标准库所有异常类的基类



4-2
Exception Classes in Standard Library(标准库中的异常类)
注意,在使用所有标准库异常类的时候,都必须附加std名字空间。
例如,在使用 bad_alloc 异常类时:

std::bad_alloc  ex{"Out of memory"};
throw ex;




Not to Use Exceptions (何时不用异常)
2.1. Simple errors that may occur in individual functions are best handled locally without 
throwing exceptions. (只发生在单独函数中的简单错误不要用异常处理)
2.2. Do not use throw to indicate a coding error in usage of a function (不要用异常处理编码错误)
可以用assert()中断程序执行然后调试 
2.3. Do not use exceptions for control flow (不要用异常来控制程序流程)

不要用throw来结束循环!!!
实时系统中不用异常(航天飞机控制程序、生命维持系统等)



规范:
23. The prefix n should be used for variables representing a number of objects.
表示对象数量的变量名应加前缀 n

例如:nPoints, nLines

 

24.The suffix No should be used for variables representing an entity number.
代表实体编号的变量应加后缀 No

例如:tableNo, employeeNo
另外一种比较优雅的替代方法是,给这种变量加上前缀 i,例如: iTable, iEmployee. 这样让他们的名字变成
一个迭代器



















在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
(不过由于我们传e是传的引用,所以可以直接调用e.what()即可获得正确的答案)

重抛出异常:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值