c++peimer之用于大型程序的工具

2021/6/18 1:05:09

本文主要是介绍c++peimer之用于大型程序的工具,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并做出相应的处理

二、异常使得我们能够将问题的检测与解决过程分离开

三、通过抛出一条表达式来引发一个异常

四、当执行一个throw时,跟在throw后面的语句将不再被执行,程序的控制权从throw转移到与之匹配的catch模块

五、控制权从一处转移到另一处,则:

1、沿着调用链的函数可能会提早退出

2、一旦程序开始执行异常处理代码,则沿着调用链创建的对象将被销毁

六、当throw在一个try语句块内时,检查与该try块关联的catch子句

七、栈展开过程沿着嵌套函数的调用链不断查找,直到找到了与异常匹配的catch子句为止,或者也可能一直没找到匹配的catch,则退出主函数后查找过程终止

八、如果栈展开过程中退出了某个块,编译器将负责确保在这个块中创建的对象被正确的销毁。如果某个局部对象的类型是类类型,则该对象的析构函数将被自动调用

九、出于栈展开可能使用析构函数的考虑,析构函数不应该抛出不能被它自己处理的异常

十、异常对象是一种特殊的对象,编译器使用异常抛出表达式来对异常对象进行拷贝初始化。因此,throw语句中的表达式必须拥有完全类型。而且如果该表达式是类类型的话,则相应的类必须含有一个可访问的析构函数和一个可访问的拷贝或移动构造函数。如果该表达式是数组类型或函数类型,则表达式将被转换成与之对应的指针类型

十一、抛出一个执行局部对象的指针几乎肯定是一种错误的行为,同样,从函数中返回指向局部对象的指针也是错误的

十二、如果一条throw表达式解引用一个基类指针,而该指针实际指向的是派生类对象,则抛出的对象将被切掉一部分,只有基类部分被抛出

十三、catch子句中异常声明的类型决定了处理代码所能捕获的异常类型,这个类型必须是完全类型,它可以是左值引用,但不能是右值引用

十四、如果catch的参数类型是非引用类型,则该参数是异常对象的要给副本,在catch语句内改变该参数实际上改变的是局部副本而非异常对象本身;如果参数是引用类型,则和其他引用参数一样,该参数是异常的一个别名,此时改变参数也就是改变异常对象

十五、如果catch参数是基类类型,则可以使用其派生类类型的异常对象对其进行初始化。此时,如果catch的参数是非引用类型,则异常对象将被切掉一部分;如果catch的参数是基类的引用,则该参数将以常规方式绑定到异常对象上

十六、通常情况下,如果catch接受的异常于某个继承体系有关,则最好将该catch的参数定义成引用类型

十七、一般要求异常的类型和catch声明的类型精确匹配:

1、允许从非常量向常量的类型转换

2、允许从派生类向基类的类型转换

3、数组被转换成指向数组类型的指针,函数被转换成指向该函数类型的指针

十八、一条catch语句通过重新抛出的操作将异常传递给另一个catch语句,重新抛出是一条throw语句,只不过不包含任何表达式: throw;

十九、空的throw语句只能出现在catch语句或catch语句直接或间接调用的函数之内

二十、有时catch语句会改变其参数的内容,如果在改变了参数的内容后catch语句重新抛出异常,则只有当catch异常声明是引用类型时我们对参数所做的改变才会被保留并继续传播

二一、为了一次性捕获所有异常,使用省略号作为异常的声明:catch(...)

二二、catch(...)通常与重新抛出语句一起使用

二三、要想处理构造函数初始值抛出的异常,必须将构造函数写成函数try语句块的形式,关键字try出现在表示构造函数初始值列表的冒号以及表示构造函数体的花括号之前:Foo(const data) try : data(data)

二四、通过提供noexcept说明指定的某个函数不会抛出异常,其形式是关键字noexcept紧跟在函数的参数列表后面

二五、noexcept说明要么出现在函数的所有声明语句和定义语句中,要么一次也不出现

二六、可以在函数指针的声明和定义中使用noexcept;在typedef或类型别名中不能出现noexcept;在成员函数中,noexcept说明符需要跟在const以及引用限定符之后,而在final、override或虚函数的=0之前

二七、一旦一个noexcept函数抛出了异常,程序会调用terminate终止程序

二八、noexcept说明符接受一个可选的实参,该实参必须能转换位bool类型,如果实参是true,则函数不会抛出异常,如果为false,则函数可能抛出异常

二九、noexcept也可以作为运算符,noexcept运算符是一个一元运算符,它的返回值是一个bool类型的右值常量表达式,用于表示给定的表达式是否会抛出异常: noexcept(e)

三十、如果为某个指针做出了不抛出异常的声明,则该指针将只能指向不抛出异常的函数;如果一个虚函数做出了不抛出异常声明,则后续派生出来的虚函数也必须做出同样的声明; 如果对所有成员和基类的所有操作都做出了不会抛出异常的声明,则合成的成员是noexcept的

三一、类型exception仅仅定义了拷贝构造函数、拷贝赋值运算符、一个虚析构函数和一个what的虚成员,what返回一个const char*,该指针指向一个以null结尾的字符数组,并且确保不会抛出任何异常

三二、类exception、bad_cast、bad_balloc定义了默认构造函数;类runtime_error、logic_error没有默认构造函数,但有一个接受c风格字符串或者标准库string类型实参的构造函数

三三、exception划分为2大类: 运行时错误和逻辑错误

三四、命名空间分割了全局命名空间,其中每个命名空间是一个作用域

三五、一个命名空间的定义包含2部分:首先是关键字namesapce。随后是命名空间的名字。在命名空间名字后面是一系列由花括号括起来的声明和定义

三六、命名空间可以定义在全局作用域内,也可以定义在其他命名空间内,但不能定义在函数或类的内部

三七、定义在某个命名空间中的名字可以被该命名空间内的其他成员直接访问,也可以被这些成员内嵌作用域中的任何单位访问。位于该命名空间外的代码则必须明确指出所用的名字属于哪个命名空间

三八、命名空间可以定义在几个不同的部分

三九、通常情况下,不把#include放在命名空间内部,如果放在内部,隐含的意思是把头文件中所有的名字定义成该命名空间的成员

四十、可以在命名空间定义的外部定义该命名空间的成员,命名空间对于名字的声明必须在作用域内,同时该名字的定义需要明确指出其所属的命名空间

namespace npc {}

npc::Foo

四一、全局命名空间以隐式的方式声明,并且在所有程序中都存在。作用域运算符同样可以用于全局命名空间: ::Foo

四二、内联命名空间中的名字可以白外层命名空间直接使用,定义内联命名空间的方式是在关键字namespace前添加关键字inline

四三、未命名的命名空间是指关键字namespace后紧跟花括号括起来的一系列声明语句。未命名的命名空间中定义的变量拥有静态声明周期,它们在第一次使用前创建,直到程序结束才销毁

四四、如果2个文件都含有未命名的命名空间,则它们相互无关。如果一个头文件中定义了未命名的命名空间,则该命名空间中定义的名字将在每个包含了该头文件的文件中对应不同实体

四五、定义在未命名的命名空间中的名字可以直接使用,不能对未命名的命名空间的成员使用作用域运算符

四六、如果未命名的命名空间定义在文件的最外层作用域中,则该命名空间中的名字一定要与全局作用域中的名字区分开

四七、一个未命名的命名空间也能嵌套在其他命名空间中,此时,未命名的命名空间中的成员可以通过外层命名空间的名字来访问

四八、命名空间的别名声明以关键字namespace开始,后面是别名的名字=命名空间的名字

四九、一条using声明语句一次只引入命名空间中的一个成员,可以出现在全局作用域、局部作用域、命名空间作用域以及类的作用域

五十、一条using指示以关键字using开始,后面是关键字namespace以及命名空间的名字。using指示可以出现在全局作用域、局部作用域和命名空间作用域中,但不能出现在类的作用域中

五一、using声明只是简单的令名字在局部作用域内有效;using指示是令整个命名空间的所有内容变得有效

五二、当给函数传递一个类类型的对象时,除了在常规的作用域查找还会查找实参类所属的命名空间,对于传递类的引用或指针同样有效: std::string s; std::cin >> s; 等价于 operator >> (std::cin, s)

五三、using声明语句声明的是一个名字,而非一个特定的函数

五四、一个using声明引入的函数将重载该声明语句所属作用域中已有的其他同名函数。如果using声明出现在局部作用域中,则引入的名字将隐藏外层作用域的相关声明,如果using声明所在的作用域中已经有一个函数与新引入的函数同名且形参列表相同,则该using声明将引发错误

五五、using指示将命名空间的成员提升到外层作用域中,如果命名空间的某个函数与该命名空间所属作用域的函数同名,则命名空间的函数将被添加到重载集合中

五六、对于using指示,引入一个与已有函数形参列表完全相同的函数并不会产生错误,只要指明调用的是命名空间中的函数还是当前作用域中的函数

五七、多重继承中基类的构造顺序与派生列表中的基类出现的顺序保持一致,析构函数则相反

五八、在默认情况下,派生类中含有继承链上每个类对应的子部分,如果某个类在派生过程中出现了多次,则派生类中将包含该类的多个子对象。可以通过虚继承的机制解决这个问题。

class ZooAnimal
{

};


class Bear : public ZooAnimal
{

};

// 虚继承解决继承体系中某个基类出现多次的问题
class Raccoon : public virtual ZooAnimal
{

};

class Endangered
{

};



class Panda : public Bear, public Endangered
{
	// 基类的构造顺序与派生列表中基类的出现顺序一致
	// ZooAnimal - Bear - Endangered - Panda
	// 析构函数的调用与构造函数想法
	// ~Panda - ~Endangered - ~Bear - ~ZooAnimal
};

class OutOfStock : public runtime_error
{
public:
	explicit OutOfStock(const string& s) : runtime_error(s) {}
};

class IsbnMismatch : public logic_error
{
public:
	explicit IsbnMismatch(const string& s) : logic_error(s) {}
};

namespace blip {
	int i = 16, j = 15, k = 20;
}

int j = 0;
void manip()
{
	using namespace blip;
	//++j; // j不确定
	++::j; // 全局j
	++blip::j; // blip::j
}
int main()
{
	//throw IsbnMismatch("wrong isbn");
	return 0;
}

 



这篇关于c++peimer之用于大型程序的工具的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程