首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++构造函数函数抛出异常注意事项

语法上来说,构造函数函数都可以抛出异常。但从逻辑上和风险控制上,构造函数函数中尽量不要抛出异常,万不得已,一定要注意防止资源泄露。在函数抛出异常还要注意栈展开带来程序崩溃。...最后,由于b并没有被成功构造,所以main()函数结束时,并不会调用b函数,也就很容易造成内存泄露。 2.函数抛出异常函数中是可以抛出异常,但是这样做很危险,请尽量不要这要做。...在栈展开过程中就会调用已经在栈构造好对象函数来释放资源,此时若其他函数本身也抛出异常,则前一个异常尚未处理,又有新异常,会造成程序崩溃。...} } 在面对函数抛出异常时,程序猿要注意以下几点: (1)C++中函数执行不应该抛出异常; (2)假如函数抛出异常,那么你系统将变得非常危险,也许很长时间什么错误也不会发生...,决不能让它抛出函数之外。

2K10

C++核心准则C.36:函数不应该失败

如果函数会失败,通常我们也不知道怎么写出没有错误代码。标准库要求它处理所有的类函数都不要抛出异常。...为了发明处理函数错误可靠方法,人们已经进行了各种尝试。没有任何一种方法发展成通用做法。这是一个真正实践性问题:例如,socket不能关闭时怎么办?...函数编写者不知道函数为什么被调用,而且不能通过抛出异常来拒绝这个动作。...如果函数使用了可能失败操作,它可以自己捕捉异常并且在有些情况下依然成功地结束(例如使用抛出异常之外不同清除机制)。...(简单)如果可能抛出异常,那么函数应该声明为noexcept。 译者注:声明noexcept,编译器就不会生成异常传递机制,这时一旦抛出异常,程序会直接中止。

59430
您找到你想要的搜索结果了吗?
是的
没有找到

C++ 异常机制分析

不完全类型意味着该类型没有完整数据与操作描述),而且可以进行复制构造,这就要求异常抛出表达式复制构造函数(或移动构造函数)、函数不能是私有的。...& err ) { /* 构造函数异常处理部分 */ }; 异常机制与函数 C++不禁止函数向外界抛出异常,但函数被期望不向外界函数抛出异常。...函数中向函数抛出异常,将直接调用terminator()系统函数终止程序。如果一个函数内部抛出异常,就应该在函数内部捕获并处理异常不能异常抛出函数之外。...可以如此处理: 若函数抛出异常,调用std::abort()来终止程序。 在函数中catch捕获异常并作处理。...当抛出一个异常时,必须确定异常是不是try块中抛出异常处理机制为了完善异常和它处理器之间匹配,需要存储每个异常对象类型信息以及catch语句额外信息。

1.7K61

C++核心准则​讨论:,释放和交换操作必须永不失败

永远不要允许函数,资源释放函数(例如,运算符删除)或交换函数中使用throw报告错误。如果这些操作失败,编写有用代码几乎是不可能,发生错误,重试也几乎没有任何意义。...,而且抛出异常时,如果n函数抛出异常,则程序将通过std :: terminate退出,因为两个异常不能同时传播。...,我们将遇到相同问题,因为函数现在也可能抛出异常,如果是,std :: terminate将会被触发。...试想一下:编译器可以生成什么代码来构造arr,如果第四个对象构造函数抛出该代码,则该代码必须放弃,并在其清理模式下尝试调用已构造对象函数...这些更多函数抛出异常么?...--[C++03] §15.2(3) 如果在堆栈展开期间调用函数异常退出,则将终止(15.5.1)。因此,函数通常应捕获异常,而不应让它们传播出函数

63230

effective C++ 读书笔记 条款08「建议收藏」

条款08 别让异常逃离析函数: 假设在函数其中发生了异常,程序可能会过早结束或者导致不明白行为(异常函数传播出去) 看代码: #include using namespace...用abort阻止异常函数传播出去 } } //解决方法2:吞下异常 /* ~DBConn() { try { db.close(); } catch...假设某个操作可能在失败时抛出异常。而又存在某种须要必须处理异常,那么这个异常必须来自函数以外某个函数 由于函数吐出异常,总会带来“过早结束程序”或者“发生不明白行为”风险。...总结: 1:函数绝对不要吐出异常,假设一个被函数调用函数可能抛出异常函数应该捕捉该异常,然后吞下它们(不传播)或结束程序 2:假设客户须要对某个操作函数执行期间抛出异常做出反应,那么...*/ 1:函数绝对不要吐出异常。假设一个被函数调用函数可能抛出异常函数应该捕捉该异常

24430

Effective C++ 条款08:别让异常逃离析函数

1.别让异常逃离析函数原因 《Effective C++》第三版中条款08建议不要在函数抛出异常,原因是C++异常机制不能同时处理两个或两个以上异常。...但假设在那些调用期间,第二个widget函数抛出异常,这就出现了上面说情况,多个异常同时存在情况下,程序若不结束,会导致不明确行为。...(); } catch(...){ abort(); } } 如果程序遭遇一个“于期间发生错误”后无法继续执行,“强制结束程序”是个合理选项,毕竟它可以阻止异常函数传播出去...如果某个操作可能在失败时候抛出异常,而又存在某种需要必须处理异常,那么这个异常必须来自函数以外某个函数。因为函数吐出异常就是危险,总会带来“过早结束程序”或“发生不明确行为”风险。...请记住: (1)函数绝对不要吐出异常,如果一个被函数调用函数可能抛出异常函数应该捕捉任何异常,然后吞下它们(不传播)或结束程序。

1.1K40

【C++】异常处理 ⑥ ( 异常生命周期 | 抛出自定义类对象异常 | 自定义类对象异常生命周期 | 抛出 自定义类引用类型 异常 | 抛出 自定义类指针类型 异常 )

一、C++ 异常处理 - 抛出自定义类对象异常 1、抛出 异常对象 如果 抛出 指针类型 , 指向是 实际对象 , 那么就要涉及到 对象 内存空间 分配 与 释放 ; 涉及到 内存空间 申请...、异常类设置 构造函数 / 函数 / 拷贝构造函数异常对象类设置 构造函数 , 函数 , 拷贝构造函数 ; 分析 异常对象 在不同阶段 构造 和 情况 ; class Exception3...; 调用函数 : catch 捕获异常分支代码执行完毕后 , 在最后一个大括号 } 结尾 , 就会将 异常对象 掉 , 抛出异常 和 传递异常变量 都会同时被 ; // 抛出异常...异常 " << endl; } 抛出异常到拦截异常打印日志如下 : Exception3 构造函数 出现 Exception3 异常 Exception3 函数 try-catch 代码块执行完毕...掉 , 抛出异常 会被 ; // 抛出异常 如果要在 catch 分支中访问 // 需要调用 拷贝构造函数异常对象传递给 catch 分支中异常变量 catch (Exception3

15210

《C++Primer》第十八章 用于大型程序工具

因此我们使用类来控制资源分配,就能确保无论函数正常结束还是遭遇异常,资源都能被正常释放。 由于栈展开可能使用函数,因此函数不应该抛出不能被它自身处理异常。...换句话说,如果函数需要执行某个可能正常抛出异常操作,则该操作也应该被放置在一个try语句块当中,并且在函数内部得到处理。...(在实际编程过程中,因为函数仅仅是释放资源,所有他不太可能抛出异常,所有标准库类型都能确保它们函数不会抛出异常)。 在栈展开过程中,运行类类型局部对象函数。...因为这些函数是自动执行,所以它们不应该抛出异常。一旦在栈展开过程中函数抛出异常,并且函数自身没能捕获到该异常,则程序被终止。...,则抛出对象将被切掉一部分之后基类部分被抛出) 2.捕获异常 2.1 重新抛出 有时一个单独catch语句不能完整地处理某个异常

1.3K20

是否能在构造函数函数抛出异常

虽然C++并不禁止函数抛出异常,但这样会导致程序过早结束或出现不明确行为。      2. 如果某个操作可能会抛出异常,class应提供一个普通函数(而非函数),来执行该操作。...目的是给客户一个处理错误机会。      3. 如果函数异常非抛不可,那就用try catch来将异常吞下,但这样方法并不好,我们提倡有错早些报出来。 二.  ...构造函数抛出异常,会导致函数不能被调用,但对象本身已申请到内存资源会被系统释放(已申请到资源内部成员变量会被系统依次逆序调用其函数)。      2....因为函数不能被调用,所以可能会造成内存泄露或系统资源未被释放。      3. 构造函数中可以抛出异常,但必须保证在构造函数抛出异常之前,把系统资源释放掉,防止内存泄露。(如何保证???...构造函数中尽量不要抛出异常,能避免就避免,如果必须,要考虑不要内存泄露! 2. 不要在函数抛出异常! 本文参考: 1. 《Effective C++》条款08:别让异常逃离析函数。 2.

3.5K50

c++:动态库接口函数返回stl对象设计原则塈‘__acrt_first_block == header’异常

https://blog.csdn.net/10km/article/details/80522287 问题描述 最近在写dll动态库时,动态库函数返回std::string对象在抛出异常...; } 原因分析 关于__acrt_first_block == header异常,google上查了一下,根本原因是对象在时不正确释放内存导致。...在main结束时要result,会调用exe中实例化std::string函数代码来释放内存,然后就会抛出__acrt_first_block == header异常。...返回std::string,result内存是由dll分配 std::cout << result << std::endl; } // result时抛出异常 如果和exe和动态库都是/MD...代码如下: /* 用于dll分配资源Traii管理类,时自动正确释放资源 * T为资源类型,外部不可修改 */ template class raii_dll

4.1K30

C++ Primer 学习笔记_87_用于大型程序工具 –异常处理

运行局部对象函数,由类类型对象分配资源通常由它们函数释放。...2、函数应该从不抛出异常 在为某个异常进行栈展开时候,函数假设又抛出自己未经处理还有一个异常,将会导致调用标准库terminate函数。...一般而言,terminate函数将调用abort函数,强制整个程序非正常退出。 由于terminate函数结束程序,所以函数做不论什么可能导致异常事情通常都是很糟糕主意。...在实践中,由于函数释放资源,所以它不太可能抛出异常。标准库类型都保证它们函数不会引发异常。 3、异常与构造函数 构造函数内部所作事情常常会抛出异常。...4、未捕获异常终止程序 不能处理异常异常是足够重要、使程序不能继续正常运行事件。假设找不到匹配catch,程序就调用库函数terminate[你懂得。。。]!

69010

由浅入深学习单例模式

我们知道在类编译时,编译器都会默认生成以下四个函数:构造函数,拷贝构造函数函数以及赋值运算符重载函数。这四个函数默认都是public型,保证外部能够调用。...通过这四个函数外部可以实例化对象,拷贝对象,等等。那很容易想到,把这四个函数设置为private就可以避免类在外部被实例化了。 最后,如何保证线程安全性呢。...如果返回对象,对象就在外面,就要在外面来销毁,而函数是私有的,所以不能有外面来销毁。...CSingleInstanceB::InnerHelper CSingleInstanceB::ih;//注意使用时,静态局部对象要在外部初始化,否则是无法进入构造和函数。...加锁模式中,通过引入了一个Lockwrapper类,同样借助了函数一定会执行特性,保证锁一定能被释放。 单例模板 引入模板来实现一个通用化单例模式。

39470

C++ 函数不要抛出异常

语法上来说,函数可以抛出异常,但从逻辑上和风险控制上,函数中不要抛出异常,因为栈展开容易导致资源泄露和程序崩溃,所以别让异常逃离析函数。...1.函数抛出异常问题 函数语法上是可以抛出异常,但是这样做很危险,请尽量不要这要做。...在栈展开过程中就会调用已经在栈构造好对象函数来释放资源,此时若其他函数本身也抛出异常,则前一个异常尚未处理,又有新异常,会造成程序崩溃。...如果某个操作可能在失败时候抛出异常,而又存在某种需要必须处理异常,那么这个异常必须来自函数以外某个函数。因为函数吐出异常就是危险,总会带来“过早结束程序”或“发生不明确行为”风险。...如果函数发生异常,不要让异常逃离析函数函数应该捕捉任何异常,不传播或结束程序; (3)如果客户需要对某个操作函数运行期间抛出异常作出反应,那么class应该提供一个普通函数(而非在函数

1.1K40

工作中常见几种内存泄漏场景汇总

但是当传入参数为0时,运行代码后抛出异常。进程退出,异常信息如下图所示: 结果可以看出,抛出异常后代码退出,但是类函数没有被调用。...这也说明如果在构造函数抛出异常,类函数是不会被调用。所以如果要在构造函数中使用抛出异常,那么切记,一定要在抛出异常前对申请资源进行正确释放。反之,就像上面的代码一样,产生内存泄漏风险。...这是因为,在基类中并没有定义函数,在这种情况下,编译器会为我们默认生成一个函数,但还不够智能,生成函数不是虚拟,这样在对基类指针进行时就不能调用子类函数释放资源。...但是这样做就破坏了delete工作原理,delete删除对象时,先调用对象函数,再delete指针对象,上面的代码在将pBase转换成void*后,delete获取不到对象类型就不能正确调用对象函数...,需要我们手动进行处理,要想得到正确代码,按照如下方式进行修改: for(int i=0;i<vTest.size();i++) { delete vTest[i]; } 代码运行后,结果可知

91220

C++11 在函数中执行lambda表达式(std::function)捕获this指针陷阱

然而当我在VisualStudio2015下同样运行这段代码,却抛出异常。。。仔细跟踪分析,发现当程序到下图箭头所指位置时,test_lambda成员变量fun显示是empty。...这就是异常发生直接原因。。。 一开始总是在纠结为什么gcc和vs2015下运行结果不一样,既然在gcc下运行正常说明代码逻辑没问题,这该不会是vs2015一个bug吧?...还得代码上找原因。 将上图箭头位置lambda表达式捕获列表改为[=],[&],都试过了,问题依旧:gcc下正常,vs2015下异常。...std::function对象已经被清除了,这时fun已经是个无效变量,执行它当然会抛出异常。...同样用前面在std::function函数加断点方式在eclipse+gcc环境下做了测试,测试结果表明gcc也是按C++标准顺序执行对象,但不同是gcc在构造下面这个lambda表达式时

1.4K10

如何设计一个C++类?

反正每次定义一个类时候都会明确把构造函数函数写出来,即便它是空实现,即便不写编译器也会视情况默认生成一个,自动生成称为默认构造函数。...如果确认某个函数不会抛出异常,那就标记为noexcept,这样编译器可以对函数做进一步优化(具体做了什么优化,也不知道),提供程序运行效率,总之,尽量把能标记为noexcept都标记为noexcept...这里抛砖引玉下,如果是服务端编程,建议使用异常处理替代错误码错误处理方式,关于异常处理有两个常见问题: 构造函数可以使用异常函数可以使用异常吗?...结论是构造函数处理错误时可以使用异常,而且建议使用异常函数中也可以使用异常,但不要让异常函数中逃离,有异常要在函数中捕获处理掉。...暴露给用户头文件要想清楚该暴露什么,不该暴露什么,外部头文件不要引用内部头文件 类成员变量确保作保初始化工作 不要让异常逃离析函数 构造函数函数不要调用虚函数 不要返回函数局部对象指针或引用

1.5K20

细说new与malloc10点区别

当时回答new自由存储区上分配内存,malloc堆上分配内存;new/delete会调用构造函数/函数对对象进行初始化与销毁;operator new/delete可以进行重载;然后强行分析了一下自由存储区与堆区别...第二步:编译器调用operator delete(或operator delete[])函数释放内存空间。 总之来说,new/delete会调用对象构造函数/函数以完成对象构造/。...可以看出A默认构造函数并没有被调用,因为数据成员a,b值并没有得到初始化,这也是上面为什么说使用malloc/free来处理C++自定义类型不合适,其实不止自定义类型,标准库中凡是需要构造/类型通通不合适...客户处理内存分配不足 在operator new抛出异常以反映一个未获得满足需求之前,它会先调用一个用户指定错误处理函数,这就是new-handler。...构造函数函数 调用 不调用 malloc给你就好像一块原始土地,你要种什么需要自己在土地上来播种 ?

1.4K52

【笔记】《C++Primer》—— 第18章:用于大型程序工具

rised一个异常,然后调用链中与类型匹配最近handler会处理这个异常,被抛出异常中携带信息会协助处理部分进行处理。...,此时编译器将负责保证其中对象销毁,此时这些对象函数会自动调用 但是异常可能在任何地方出现,即使在函数中也是一样,为了保证正常我们需要自己保证时不应该抛出自己无法处理异常到外层...,而应该保证自己能完整所有成员,否则很容易就会进入terminate。...标准库类型都保证自己不会抛出异常 异常自然也可能在构造函数出现,如果我们在构造函数体中初始化成员自然可以用try-catch处理,但是初始值列表在返回之外,为了处理初始值列表异常我们需要用函数try...,不用特指,和模板内部调用成员类似 我们也可以在命名空间外部定义命名空间内成员,但是注意只能是在外层,不能在不相干同级作用域中定义 全局作用域实际上是一个无名命名空间,我们用::XXX来特指 C11

93220

《Effective C++》读书笔记(2):构造赋值运算

/函数是只是调用基类和非静态成员变量构造函数/函数;生成函数是非虚,除非基类有虚函数。...---- 条款8、别让异常逃离析函数 C++中抛出异常时会逐步展开其函数调用栈,清空局部资源,直到异常被catch。...如果函数可以抛出异常,那么清空局部资源时局部对象函数再次异常时同时存在两个异常,C++无法处理,可能会过早结束或出现不明确行为。...因此,函数绝对不要抛出异常,应通过try-catch捕获任何异常。 有时,客户需要处理某些异常,那么类应该提供一个普通成员函数执行相关操作,供用户调用并处理异常。...例如数据库连接这样类中,假设用户需要处理关闭连接时异常,同时函数不能抛出异常,可以这样: class DBConn{ public: void close(){ db.close()

13230

从零开始学C++之异常(二):程序错误、异常(语法、抛出、捕获、传播)、栈展开

(类型2  参数2) { //针对类型2异常处理 } … catch (类型n  参数n) { //针对类型n异常处理 } (二)、异常抛出 可以抛出内置类型异常也可以抛出自定义类型异常...throw抛出一个类对象会调用拷贝构造函数 异常发生之前创建局部对象被销毁,这一过程称为栈展开 (三)、异常捕获 一个异常处理器一般只捕捉一种类型异常 异常处理参数类型和抛出异常类型相同...程序自定义一个异常类型MyException,输出可以看出,Divide函数内先构造一个MyException对象e,调用构造函数,因为e是局部对象需要被,在前先调用拷贝构造函数构造另一个对象...(四)、异常传播 1、try块可以嵌套 2、程序按顺序寻找匹配异常处理器,抛出异常将被第一个类型符合异常处理器捕获 如果内层try块后面没有找到合适异常处理器,该异常向外传播,到外层try...为局部对象调用函数 函数应该从不抛出异常 栈展开期间会执行函数,在执行函数时候,已经引发异常但还没处理,如果这个过程中函数抛出异常,将会调用标准库terminate

1.1K00
领券