为“异常安全”而努力是值得的——条款29

OpenCLI入门:让任何网站变成你的命令行工具(超详细版) 最有用的工具,往往是最简单的。 opencli就是这样。 它不会帮你写代码,不会帮你做决策,但它能把200+个平台装进你的命令行。 让你用最简单的方式,获取最丰富的数据。 阅读详情

        异常安全性(Exception safety)有几分像是......呃......怀孕。但等等,在我们完成求偶之前,实在无法确定地谈论生育。

        假设有个class用来表现夹带背景图案的GUI菜单。这个class希望用于多线程环境,所以它有个互斥器(mutex)作为并发控制(concurrency control)只用:

class PrettyMenu {
public:
	...
	void changeBackground(std::istream& imgSrc);  // 改变背景
	...
private:
	Mutex mutex;                 // 互斥器
	Image* bgImage;              // 目前的背景图像
	int imageChanges;            // 背景图像被改变的次数 
};

下面是PrettyMenu的changeBackground函数的一个可能实现:

void PrettyMenu::changeBackground(std::istream& imgSrc)
{
	lock(&mutex);                   // 取得互斥器
	delete bgImage;                 // 摆脱旧的背景图
	++imageChanges;                 // 修改图像变更次数
	bgImage = new Image(imgSrc);    // 安装新的背景图像
	unlock(&mutex);                 // 释放互斥器
}

        从“异常安全性”的观点来看,这个函数很糟。“异常安全”有两个条件,而这个函数没有满足其中任何一个条件。当异常被抛出时,带有异常安全性的函数会:

  • 不泄露任何资源。上述代码没有做到这一点,因为一旦“new Image(imgSrc)”导致异常,对unlock的调用绝不会执行,于是互斥器就永远被把持住了。
  • 不允许数据败坏。如果“new Image(imgSrc)”抛出异常,bgImage就是指向一个已被删除的对象,imageChanges也已被累加,而其实并没有新的图像被成功安装起来。(但从另一个角度说,旧图像已被消除,所以你可能会争辩说图像还是被“改变了”)。

        解决资源泄漏的问题很容易,因为条款13讨论如何以对象管理资源,而条款14也导入了Lock class作为一种“确保互斥器被及时释放”的方法:

void PrettyMenu::changeBackground(std::istream& imgSrc)
{
	lock ml(&mutex);                // 获得互斥器并确保它稍后被释放
	delete bgImage;                 // 摆脱旧的背景图
	++imageChanges;                 // 修改图像变更次数
	bgImage = new Image(imgSrc);    // 安装新的背景图像
}

        把资源泄漏抛诸脑后,现在我们可以专注解决数据的败坏了。此刻我们需要做个抉择,但是在我们能够抉择之前,必须先面对一些用来定义选项的术语。

        异常安全函数(Exception-safe functions)提供以下三个保证之一:

  • 基本承诺:如果异常抛出,程序内任何事物仍然保持在有效状态下。没有任何对象或数据结构会因此而败坏,所有对象都处于一种内部前后一致的状态。然而程序的现实状态恐怕不可预料。例如,我们可以撰写changeBackground使得一旦有一次被抛出时,PrettyMenu可以继续拥有原背景图像,或是令它拥有某个缺省背景图像,但客户无法预期哪一种情况。如果想知道,他们恐怕必须调用某个成员函数以得知当时的背景图像是什么。
  • 强烈保证:如果异常被抛出,程序状态不改变。调用这样的函数需有这样的认知:如果函数成功,就完全成功,如果函数失败,程序会回到“调用函数之前”的状态。
  • 不抛异常(nothrow)保证:承诺绝不抛出异常,因为它们总是能够完成它们原先承诺的功能。作用于内置类型(例如ints,指针等)身上的所有操作都提供nothrow保证。这是异常安全码中一个必不可少的关键基础材料。

        对changeBackground而言,提供强烈保证几乎不困难。首先改变PrettyMenu的bgImage成员变量的类型,从一个类型为Image*的内置指针改为一个“用于资源管理”的智能指针(见条款13)。坦白说,这个好构想纯粹只是帮助我们防止资源泄漏。

        第二,我们重新排列changeBackground内的语句次序,使得在更换图像之后才累加imageChanges。一般而言这是个好策略:不要为了表示某件事情而改变对象状态,除非那件事情真的发生了。

        下面是结果:

class PrettyMenu {
	...
	std::tr1::shared_ptr<Image> bgImage;
	...
};
void PrettyMenu::changeBackground(std::istream& imgSrc)
{
	Lock ml(&mutex);
	bgImage.reset(new Image(imgSrc));  // 以"new Image"的执行结果设定bgImage内部指针
	++imageChanges;
}

        注意,这里不再需要手动delete旧图像,因为这个动作已经有智能指针内部处理掉了。此外,删除动作只发生在新图像被成功创建之后。更正确地说,tr1::shared_ptr::reset函数只有在其参数(也就是“new Image(imgSrc)”的执行结果)被成功生成之后才会被调用。delete只在reset函数内被使用,所以如果从未进入那个函数也就绝对不会使用delete。也请注意,以对象(tr1::shared_ptr)管理资源(这里是动态分配而得的Image)再次缩减了changeBackground的长度。

        这两个改变几乎足够让changeBackground提供强烈的异常安全保证。美中不足的是参数imgSrc。如果Image构造函数抛出异常,有可能输入流(input stream)的读取记号(read marker)已被移走,而这样的搬移对程序其余部分是一种可见的状态改变。所以changeBackground在解决这个问题之前只提供基本的异常安全保证。

        有个一般化的设计策略很典型地会导致强烈保证,很值得熟悉它。这个策略被称为copy and swap。原则很简单:为你打算修改的对象(原件)做出一份副本,然后在那副本身上做一切必要修改。若有任何修改动作抛出异常,源对象仍保持未改变状态。待所有改变都成功后,再将修改过的那个副本和原对象在一个不抛出异常的操作中置换(swap)。

        实现上,通常是将所有“隶属对象的数据”从原对象放进另一个对象内,然后赋予原对象一个指针,指向那个所谓的实现对象(implementation object,即副本)。这种手法常被称为pimpl idiom,条款31详细描述了它。对PrettyMenu而言,典型写法如下:

struct PMImpl {                             // PMImpl="PrettyMenu Impl";
	std::tr1::shared_ptr<Image> bgImage;  // 稍后说明为什么它是个struct 
	int imageChanges;
}
class PrettyMenu {
	...
private:
	Mutex mutex;
	std::tr1::shared_ptr<PMImpl> pImpl;
};
void PrettyMenu::changeBackground(std::istream& imgSrc)
{
	using std::swap;                                        // 见条款25
	Lock ml(&mutex);                                        // 获得mutex的副本数据
	std::tr1::shared_ptr<PMImpl> pNew(new PMImpl(*pImpl));
	pNew->bgImage.reset(new Image(imgSrc));                 // 修改副本
	++pNew->imageChanges;
	swap(pImpl, pNew);                                      // 置换(swap)数据,释放mutex
}

        此例之中我选择让PMImpl称为一个struct而不是一个class,这是因为PrettyMenu的数据封装性已经由于“pImpl是private”而获得了保证。如果令PMImpl为一个class,虽然一样好,有时候却不太方便(但也保持了面向对象纯度)。比如打包问题。

       “copy-and-swap”策略是对对象状态做出“全有或全无”改变的一个很好办法,但一般而言它并不保证整个函数有强烈的异常安全性。比如函数中包含其它函数:

void someFunc()
{
	...      // 对local状态做一份副本
	f1();
	f2();
	...      // 将修改后的状态置换过来
}

        上述这种情况就很难保证someFunc的异常安全性了,即使f1和f2都是“强烈异常安全”,情况并不好转。毕竟如果f1圆满结束,程序状态在任何方面都可能有所改变,因此如果f2随后抛出异常,程序状态和someFunc被调用前并不相同,甚至当f2没有改变任何东西也是如此。

        问题出在“连带影响”(side effects)。如果函数只操作局部性状态(local state,例如someFunc只影响其“调用者对象”的状态),便相对容易地提供强烈保证。但是当函数对“非局部性数据”(non-local data)有连带影响时,提供强烈保证就困难得多。举个例子,如果调用f1带来的影响是某个数据库被改动了,那就很难让someFunc具备强烈安全性。一般而言在“数据库修改动作”送出之后,没有什么做法可以取消并恢复数据库旧观,意味数据库的其他客户可能已经看到了这一笔新数据。

请记住

  • 异常安全函数(Exception-safe functions)即使发生异常也不会泄漏资源或允许任何数据结构败坏。这样的函数区分为三种可能的保证:基本型、强烈型、不抛异常型。
  • “强烈保证”往往能够以copy-and-swap实现出来,但“强烈保证”并非对所有函数都可实现或具备现实意义。
  • 函数提供的“异常安全保证”通常最高只等于其所调用之各个函数的“异常安全保证”中的最弱者。

个人观点:在实际项目开发中,我们应该避免内存泄漏和数据被破坏的情况,但是要做到上述所说的不抛异常型函数很难,会耗费大量的时间去设计,增加项目开发成本。不过作为开发者,至少要了解这方面可能存在的问题,争取写出优质的代码。

24、无人机能耗模型与上下文质量管理的研究 本文系统介绍了无人机能耗模型与上下文质量管理的研究进展。详细阐述了Dorling、Stolaroff、Kirchstein和Tseng等经典能耗模型的原理及特点,并基于LSTM架构构建了数据驱动的能耗预测模型,实验表明其预测精度显著优于传统模型。此外,还探讨了物联网环境中的上下文质量管理问题,引入了conQeng框架,以提升上下文选择、测量和验证的效率与可靠性。研究为无人机能耗优化和物联网上下文管理提供了理论支持和技术方案。 阅读详情

相关推荐

Excel转LaTeX表格神器:excel2latex.xla插件使用全攻略(含下载链接与配置教程)

本文详细介绍了Excel转LaTeX表格神器excel2latex.xla插件的完整使用攻略。从下载安装、基础转换到高级配置,深入讲解了如何利用该插件高效生成LaTeX代码,特别针对IEEE双栏等复杂排版需求提供了专业解决方案,帮助用户彻底告别手动编码,提升学术与专业文档的排版效率。

app77的博客 295

条款 29 :为“异常安全”而努力是值得的

条款 29 :为“异常安全”而努力是值得的 Strive for exception-safe code. 假设有一个class用来表现带背景的GUI菜单。希望其用于多线程环境,所以他得有一个互斥器作为并发控制之用。 class PrettyMenu{ public: ... void changeBackground(std::istream& imgSrc);//改变背景图片 ... private: Mutex mutex;//互斥器 Image*

weixin_45730130的博客 229

华为云Stack的学习(三)

LVS是四层负载均衡,建立在OSI模型的传输层之上,所以效率非常高。NAT模式的转发主要通过修改IP地址(位于OSI模型的第三层网络层)实现转发。DR模式的转发主要通过修改MAC地址(位于OSI模型的第二层数据链路层)实现转发。云服务框架中使用的DR模式。域名解析服务器分为管理侧(OM)和租户侧(Tenant)**DNS-OM:**作为云服务的本地DNS服务器,为云服务提供域名解析服务,并代理公网域名的解析。

Ciyaso的博客 8561

为“异常安全”而努力是值得的

一.异常安全函数(Exception-safe function)即使发生异常也不会泄露资源或允许任何数据结构败坏,这样的函数区分为三种可能的保证:基本型、强烈型、不抛出异常型。 1)基本承诺:如果异常被抛出,程序内的任何事物仍然保持在有效状态,没有任何对象或数据结构会因此而败坏,所有对象都处于一个内部前后一致的状态(例如所有的classes约束条件都继续获得满足)。然后程序的现实状态(exac

享受开发技术,享受计算机科学 2095

【网络安全的神秘世界】解决dvwa靶场报错:Illegal mix of collations for operation ‘UNION‘

我的 information_schema 使用的是 utf8_general_ci。请根据您的实际情况调整字符集。这通常意味着在执行 UNION 操作时,不同字符集的数据发生了混合,导致冲突。修改字符集设置后,重启 MySQL 服务以应用更改,再次测试一下发现成功。查看 information_schema 的字符集。修改 DVWA 数据库字符集。

菜鸟小羊的博客 2044

ESP32S3学习——i2c,点亮0.96寸oled

ESP32S3学习——i2c,点亮0.96寸oled

HandBAI的博客 1万+

为异常安全而努力是值得的

2016年3月20日 第三周 星期天 天气:阴 Effective C++ 127页 条款29:为“异常安全” 而努力是值得的。 “异常安全”有两个条件: 1、不泄漏任何资源。 2、不允许数据破坏。 ...

丰哥的专栏 457

基于深度学习的番茄成熟度检测系统——YOLOv5、YOLOv8、YOLOv10及UI界面的实现

YOLO是一种快速且准确的目标检测模型,近年来,YOLOv5、YOLOv8和YOLOv10作为YOLO系列的重要版本,分别在速度、精度和效率上进行了优化。下面我们简要介绍这些模型。本文介绍了如何基于YOLOv5、YOLOv8和YOLOv10等深度学习模型,结合PyQt5设计一个番茄成熟度检测系统。通过训练模型、优化算法和设计用户友好的界面,我们能够构建一个高效且准确的番茄成熟度检测系统,广泛应用于农业自动化和智能化管理中。

YOLO 1002

为“异常安全的努力”是值得的——effective c++学习笔记

异常安全的两个条件: 1、 不泄露任何资源。 2、 不允许数据败坏。 对fopen函数进行封装。 异常安全函数提供下面的三个异常保证之一: 1、 基本承诺:如果异常被抛出,程序内的任何事物仍然保持在有效的状态下。没有任何对象或数据结构会因此而败坏,所有对象都处于一种内部前后一致的状态。 2、 强烈保证:如果异常被抛出,程序状态不改变。调用这样的函数需要有这样的认知:如果成功,则全部成功,如果失败,则全部失败。 3、 不抛出异常:承诺不抛出异常,因为他们总是能够完成他们之前承诺的功能。 不要为

常高伟的专栏 1425

多周期路径约束(set_multicycle_path )

1.由慢到快的多周期约束 如下图所示,发射时钟周期是接受时钟周期的4倍。默认情况下,按照1T原则来进行静态时序分析和布局布线的。即建立时间是在发射沿后的第一个捕获沿检查,而保持时间是同一时刻下源时钟和捕获时钟的触发边沿下检查的(建立时间检查边沿的前一个触发沿)。 但是这样导致的问题就是该路径过于苛刻,为了满足这条路径的要求,不得不放弃其他路径。或者根本没办法保证这个默认的约束。总之最终造成...

Arist. 5505

10.嵌入式控制器EC实战 GPIO开发流程

文章目录1.General Control Register (GCR),通用控制寄存器,地址0x1602.GPDRA—GPDRJ端口数据寄存器组(共10组)3.Port Control n Registers (GPCRn, n = A0-I7),端口控制寄存器4.GPIO端口编程指导编程步骤端口初始化使用InitGPIOReg数据结构初始化所有端口默认工作模式读取输入引脚的值(STATE_ACin()): IT8502中各个引脚的描述见下表所示: 在嵌入式控制器EC的IT8502主控芯片中,通过芯片的

qq_30135687的博客 2282

C++ 为 异常安全 而努力是值得的

20180319 C++ 为 异常安全 而努力是值得的假设有个class用来表现夹带背景图案的GUI菜单。这个class希望用于多线程环境,所以他有个互斥器(mutex)作为并发控制(concurrency control)之用:class  PrettyMenu{public:  ...  void changeBackground(std::istream&amp; imgSrc);//改变背...

weixin_39089680的博客 527

在 Eclipse 里快速用上 SAP Joule:ABAP 开发者的 AI 助手上手指南

本文介绍了SAP Joule for developers如何集成在ABAP开发工具中,为开发者提供AI辅助能力。主要内容包括: Joule作为ADT的增强层,直接嵌入开发流程,支持在项目资源管理器、代码编辑器等场景下通过上下文菜单调用AI功能。 核心使用方式:打开Joule视图后,可在开发对象、代码片段等上下文中使用自然语言交互,请求解释、生成测试或获取示例代码。 重点功能: Explain:解释现有代码逻辑,降低理解成本 ABAP Unit测试生成:快速创建与上下文相关的测试用例 支持在传输管理器等完整

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 391

条款29:为“异常安全”而努力是值得的

class PrettyMenu { public: ... void changeBackground (std::istream & imgSrc); ... private: Mutex mutex; Image* bgImage; int ImageChanges; }; void pret...

w0131的博客 233

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

条款29:为“异常安全”而努力是值得的——157

文章目录“异常安全”应该满足两个条件——157解决资源泄漏——158解决数据败坏——158结论——164 “异常安全”应该满足两个条件——157 我们来定义一个变现夹带背景图案的GUI菜单类: class PrettyMenu{ public: ... void chageBackground(std::istream& imgSrc); //改变背景图案 ...

缇珞的博客 212

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

条款29:为"异常安全"而努力是值得的

条款29:为"异常安全"而努力是值得的    (Strive for exception-safe code.)    内容:    看了这款的内容,我对C++的难以控制的"脾气"又有了进一步的了解,C++的安全性问题一直是广大非C++程序员所抨击C++语言"恶行"的主要方面,我们今天讨论的其"异常安全性"也是其复杂之处之一,看完这一款之后,你也许会发觉你以前写的代码可能会给最终产品带来多大的"风

scofieldzhu的专栏 791

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

条款29 为“异常安全”而努力是值得的

/*条款29 为“异常安全”而努力是值得的*/ #include #include using namespace std; struct PMImpl{ shared_ptrbgImage; int imagechanges; }; class Mutex{}; void lock(Mutex*mutex){ cout << "locked" << endl; } void unlock(

sbfksmq的博客 402

Effective C++ 条款 29:为 “异常安全” 而努力是值得的

目标:努力使函数具有异常安全性,保护资源完整性和逻辑一致性。层次:提供基本承诺、强烈保证或不抛异常保证,视情况而定。技术:通过 RAII、copy-and-swap 和事务性操作实现异常安全。权衡:在性能、复杂性和安全性之间找到平衡点。为异常安全而努力,不仅能提高代码健壮性,也能显著减少调试和维护的成本。

weixin_42255569的博客 480

Effective C++之条款29:为“异常安全”而努力是值得的

声明: 文中内容收集整理自《Effective C++(中文版)第三版》,版权归原书所有。 本内容在作者现有能力的基础上有所删减,另加入部分作者自己的理解,有纰漏之处敬请指正。 条款29:为“异常安全”而努力是值得的 Strive for exception-safe code. 异常安全函数提供以下三个保证之一: 基本承诺:若果异常被抛出,程序内的任何事物仍然保持在有效状态下。 强烈...

HakunaMatata的博客 485

Effective C++ 条款29 为"异常安全"而努力是值得的

1.当异常被抛出时,"异常安全"函数有两个条件: 不泄露任何资源:从堆中申请的资源应该确保被释放 不允许数据败坏:函数不能对数据修改到一半而抛出异常以致数据被破坏. 解决"不泄露任何资源"很容易,只要使用资源管理类(如shared_ptr,见条款13)即可,"不允许数据败坏"是主要考虑的问题. 2. 异常安全函数提供以下三种层次的保证: 1) ...

ddzai7557的博客 154

Effective C++ 条款29_为 “ 异常安全 ” 而努力是值得的_非同凡响

Strive for exception-safe code 异常安全性(Exception safety)有几分像是……呃…怀孕。但等等,在我们完成求偶之前,实在无法确实地谈论生育。 假设有个 class 用来表现夹带背景图案的 GUI 菜单单。这个 class 希望用于多线程环境,所以它有个互斥器(mutex)作为并发控制器(concurrency control)之用: class PrettyMenu { public: ... void changeBackground(std::istrea

嘟嘟的博客 347

条款29:为“异常安全“而努力是值得的

考虑如下代码: class PrettyMenu { public: // ... void changeBackground(std::istream& imgSrc); // 改变背景图像 // ... private: Mutex mutex; // 互斥器 Image* bgImage; // 目前背景图像 int imageChanges; // 背景图像被改变次数 }; void PrettyMenu::changeBackground(std

L_H_L的博客 165

Effective C++条款29:实现之(为“异常安全”而努力是值得的)

一、可能抛出异常的演示案例 待续

董哥的黑板报 1026
上一篇: 避免返回handles指向对象内部成分——条款28
下一篇: 透彻了解inlining的里里外外——条款30
OODeveloper
博客等级 码龄12年 43粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值