More Exceptional C++中文版试读(泛型程序设计与C++标准库)

More Exceptional C++ 读书笔记 More Exceptional C++ 读书笔记 Item 1 Switching Streams (1): 多考虑易读性,避免编写过渡简洁但是不易懂,不易维护的代码;    记个相当简洁的流切换代码:  (argc > 2 ? ofstream(argv[2], ios::out|ios::binary) : cout ) 1 ? ifstream(argv[1],      ios 阅读详情

 [Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。] 




  


泛型程序设计与C++标准库


 


 


 


C++威力强大的特性之一是对泛型程序设计(generic programming)的支持。这种威力直接反映在C++标准库的灵活性上,特别是它的容器、迭代器和算法部分,这一部分一直以来被称作标准模板库(STL)。


 


本书的开篇章节集中讨论如何最有效地使用C++标准库,尤其是STL。什么时候使用std::vector和std::deque会最有效?如何使用?在使用std::map和std::set的时候可能会碰到哪些陷阱?如何安全地避免这些陷阱?std::remove()为什么不能真正删除任何东西?


 


本章还特别介绍了一些有用的技巧和易犯的错误,在撰写自己的泛型程序代码的时候,包括撰写那些“用以和STL一起工作”或“用以扩充STL”的代码的时候,你会经常碰到它们。什么样的predicates才能安全地和STL一起使用?什么样的不行?为什么?要想让模板自身的行为可以改变,而且这种行为的改变是基于“与之协同工作的类型(type)”的能力,有什么现有的技术可以写出这种功能强大的泛型模板代码吗?如何在不同种类的输入输出流之间自如地切换?模板特殊化和重载是怎么一回事?“古怪”的typename关键字究竟有何过人之处?


 


随着对泛型程序设计和C++标准库有关话题的深入研究,我们还会碰到更多的问题。


 


 







条款1:流



难度:2




在动态地使用不同的输入输出流——包括标准控制台流(console stream)和文件时,最佳使用方式是什么?


 


1. std::cin和std::cout的类型是什么?


2. 写一个ECHO程序,让它简单地响应输入,并能通过以下两种方式等效地调用:


 



 


    ECHO <infile> outfile


    ECHO infile outfile


 


在大多数流行的命令行环境下,第一个命令假定程序从cin获得输入,并将输出发送到cout。第二个命令告诉程序从一个名为infile的文件中获得输入,并在名为outfile的文件中产生输出。这个程序应该能够支持以上所有的输入/输出选项。


 







解答


 


1. std::cin和std::cout的类型是什么?


 


简短地回答,cin实际上是:


std::basic_istream<char, std::char_traits<char> >


 


cout实际上是:


std::basic_ostream<char, std::char_traits<char> >


 


下面是较详细的回答,它通过一些标准的typedef和模板向你展示答案的来龙去脉。首先,cin和cout具有的类型分别是std::istream和std::ostream。接着,这些类型是std::basic_istream<char>和std::basic_ostream<char>的typedef。最后,考虑到模板参数的默认值,我们得到上面的答案。


 


注意:如果你使用的iostream子系统是C++标准制定之前的实现版本,你可能还会看到一些中间类(intermediate class),例如istream_with_assign。但这些类在标准中是不存在的。


 


2. 写一个ECHO程序,让它简单地响应输入,并能通过以下两种方式等效地调用:


  ECHO <infile> outfile


    ECHO infile outfile


 


最精简的方案


 


对于追求精简代码的人来说,最精简的方案莫过于下面这个程序,它仅包含一条语句:



 


// 例1-1:惊讶吗?只使用了一条语句


    //


    #include <fstream>


    #include <iostream>


 


    int main( int argc, char* argv[] )


    {


      using namespace std;


 


      (argc > 2


         ? ofstream(argv[2], ios::out | ios::binary)


         : cout)


   <<


      (argc > 1


         ? ifstream(argv[1], ios::in | ios::binary)


         : cin)


      .rdbuf();


    }


 


这个方案之所以可行,得益于两个相辅相成的条件:第一,basic_ios提供了一个方便的rdbuf()成员函数,它返回某个流对象所使用的streambuf,在本例中,这个流对象也就是cin或临时ifstream对象,二者都派生于basic_ios。第二,basic_ostream提供了一个operator<<(),它正好接受这样的basic_streambuf对象,将其作为输入,然后将输入完全读取。正如法国人会说的那样,“C'est ca”(“就是这样!”)。


 


逐步趋向更灵活的方案


例1-1中的方案有两个主要缺点:首先,精简会带来晦涩,而且过度的精简不适合应用到产品代码中。


 







设计准则




尽量提高可读性。避免撰写精简代码(即,简洁但难以理解和维护)。避免晦涩。


 


第二,虽然例1-1回答了前面的问题,但只是在对输入进行逐字拷贝的情况下,这种方法才可行。这种功能在目前可能已经够用,但如果将来你需要对输入进行其它处理,例如将字符转换成大写,或是计算字符总数,或删除第三个字符,那该怎么办?这种需要在将来是很合理的;所以,最好我们现在就立即动手,将这些处理工作封装在一个单独的函数中,使这个函数可以多态地(polymorphically)使用正确类型的输入或输出对象:



 


    #include <fstream>


    #include <iostream>


 


    int main( int argc, char* argv[] )


    {


      using namespace std;


 


      fstream in, out;


      if( argc > 1 ) in.open ( argv[1], ios::in  | ios::binary );


      if( argc > 2 ) out.open( argv[2], ios::out | ios::binary );


 


      Process( in.is_open()  ? in  : cin,


               out.is_open() ? out : cout );


    }   


 


但如何实现Process()?在C++中,主要有四种方法获得多态行为:虚函数、模板、重载和转换。其中,前两种方法可以直接用在这里,用以表达我们所需要的那种多态。


 


方法A:模板(编译时多态)


第一种方法使用的是编译时多态,这需要借助于模板;它只需要被传递的对象有一个合适的接口(例如一个名为rdbuf()的成员函数):


 


    // 例1-2(a):模板化的Process()


    //


    template<typename In, typename Out>


    void Process( In& in, Out& out ) {


      // ... 执行某种更复杂的操作,


      //     或只是简单的“out << in.rdbuf();”...


    }


 


方法B:虚函数(运行时多态)


第二种方法使用的是运行时多态,它需要一个条件,即,存在一个具有合适接口的公共基类:


 


    // 例1-2(b):第一次尝试,一定程度上可行


    //


    void Process( basic_istream<char>& in,


                  basic_ostream<char>& out )


    {


      // ... 执行某种更复杂的操作,


      //     或只是简单的“out << in.rdbuf();”...


    }



 


注意,在例1-2(b)中,Process()的参数类型不是basic_ios<char>&,因为那将不允许使用operator<<()。


 


毫无疑问,例1-2(b)中的方法具有依赖性,它要求输入和输出流必须分别从basic_istream<char>和basic_ostream<char>派生。这一点对我们的例子来说还不错,但要知道,并非所有的流都基于简单的char或者char_traits<char>。例如,宽字符流基于wchar_t,Exceptional C++ [Sutter00]的条款2和3也演示了一些具有不同行为特征的用户自定义traits(在那些例子中,ci_char_traits提供了大小写不分的行为特征),并展示了其潜在的用途。


 


因而,即使是采用方法B,我们也应该使用模板,让编译器去推导出合适的参数:


 


  // 例1-2(c):更好的方案


    //


template<typename C, typename T>


  void Process( basic_istream<C,T>& in,


                   basic_ostream<C,T>& out )


  {


      // ... 执行某种更复杂的操作,


      //     或只是简单的“out << in.rdbuf();”...


   }


 


有效的工程设计原则


就其本身而言,以上所有答案都是“正确”的;但在目前场合下,我个人倾向于选择方法A。其原因归结于两条很有价值的设计准则。第一条是:


 







设计准则




尽量提高可扩充性。


 


避免写出的代码只能解决当前问题。几乎任何时候,若能写出可扩充的方案,那将是更佳选择——当然,只要我们不太过分。


 


均衡的判断力是有经验的程序员所具有的一个特征。尤其是,在“编写专用代码,只解决当前问题”(短视,难以扩充)和“编写一个宏大的通用框架去解决本来应该很简单的问题”(追求过度设计)之间,有经验的程序员懂得如何去获取最佳的平衡。


 


较之例1-1中的方案,方法A具有大致相同的整体复杂度,但除此之外,后者还更易于理解、更具可扩充性。较之方法B,方法A既简单又更具灵活性;它更能适应新的要求,因为它没有了束缚,不只是能和iostream体系打交道。



 


所以,如果存在两个选择,它们在设计和实现中需要的工作量相同,而且具有大致相当的清晰度和可维护性,那么,请尽量考虑可扩充性。这条建议并不是在教唆你,让你去对一个本来很简单的问题大动干戈——这方面大家以前已经做得够多了。相反,这条建议是一条鼓励:如果稍微思考一下就可以发现,自己正在解决的问题实际上是某个更通用的问题的特例,你就应该多做一些工作,而不要仅仅满足于解决当前问题。这条建议十分正确,因为,在设计中提高了可扩充性,往往意味着同时提高了封装性。


 


 







设计准则




尽量提高封装性。将关系分离。


 


只要有可能,一段代码——函数或类——应该只知道并且只负责一件事。


 


可以证明,方法A最出色的地方在于:它展示了关系之间有效的分离。它包括两部分代码,一部分代码知道输入/输出源(source)和目标(sink)中可能的区别,另一部分代码知道如何真正执行处理,这两部分代码被分离开来。这种分离也使得代码的用途更清晰,更易于他人阅读和理解。将关系进行有效的分离是好的工程设计的另一个特征,在本书条款中,我们将不断地看到这一点。


 

More Exceptional C++中文版:高级C++编程进阶实战指南 异常处理从来不是一个孤立的话题。它与 RAII、模板、设计模式、编译器优化紧密交织在一起。真正厉害的程序员,不是靠“避开异常”来写出稳定代码,而是利用异常机制本身去构建更可靠的系统。就像汽车的安全气囊,你不希望它弹出来,但一旦需要,它必须起作用。这种高度集成的设计思路,正引领着现代 C++ 向更可靠、更高效的方向演进。🚀本文还有配套的精品资源,点击获取。 阅读详情

相关推荐

Exceptional.C++

Exceptional.C++中文

xx读书笔记

在本书中,Herb Sutter采用了独具匠心的“提问/解答”的方式来指导你学习C++的语言特性;在本书的每个专题中,HerbSutter合理地设想出你的疑问和困惑,又有如神助地猜到了你的(可能是错误的)解答,然后给你以指点并呈现出最佳方案,最后,还提炼解决类似问题的一般性原则。 本书适合的读者对象是中高级程序员,尽管如此,只要具备基本的C++功底和一定的程序设计经验,你完全可以理解和消化本书的

backard的专栏 643

Exceptional C++(中文版)和More Exceptional C++(中、英文版)

Exceptional C++(中文版)和More Exceptional C++(中、英文版)

more exceptional c++读书笔记

Part1 我是在读完Scott Meyers的《Effective c++》之后才读到这本书的。能够讨论特定的主题而不是将一门语言作为一个整体来看待是我理解c++的首选方式,所以Sutter和Meyers的书非常适合我。 与Meyers系列相比,exception c++系列的主要优势在于,您可以告诉Sutter是更好的程序员。你可以相信Meyers 所说的一切都是正确的,但最终你真正得到的只是一些关于如何做某些事情的额外指示。另一方面,Sutter在同样的主题上讲得更深入一些,让你觉得自己可以写出更

itaoest的博客 413

[计算机科学经典著作].Addison.Wesley.-.More.Exceptional.C++.pdf

[计算机科学经典著作].Addison.Wesley.-.More.Exceptional.C++.pdf

more exceptional c++中文版

more exceptional c++中文版

More_Exceptional_C++(中文)pdf

下载地址:网盘下载 More Exceptional C++是Exceptional C++的续篇。根据多年程序开发的实践经验、Herb Sutter向C++程序员提供了久经考验的程序设计技术和行之有效的解决方案,这些技术和方案对设计从小型工程到企业级应用的现代软件系统大有裨益。 围绕着40个编程难题, More Exceptional C++引...

weixin_30571465的博客 1115

exceptional c++ 与 more exceptional c++ 英文版

英文版 C++经典书籍 英文版看了也还行,主要是能锻炼自己,豆瓣评分8.4 加油

More Exceptional C++ 中文版试读(译序及目录)

 [Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。]  与大师面对面(译序)  小提琴家穆特录制过一张唱片,收录的是贝多芬最伟大的两部小提琴作品1。聆听那张唱片,你仿佛听见贝多芬在向你倾诉他对音乐艺术的理解和感悟、为你解答小提琴音乐创作

lostmouse的专栏 1803

从零玩转显示屏:手把手教你用Arduino驱动SPI屏幕(附引脚定义图)

本文提供了一份详尽的Arduino驱动SPI屏幕的入门指南。从SPI接口的核心引脚定义(如DC、RESET)与RGB接口的区别讲起,手把手指导硬件连接与软件库配置,并最终通过一个天气显示器实战项目,帮助读者掌握驱动SPI屏幕、显示RGB色彩内容的核心技能。

weixin_29189987的博客 132

数字孪生模型构建理论及应用

源自:计算机集成制造系统作者:陶飞 张贺 戚庆林 徐 俊 孙铮 胡天亮 刘晓军 刘庭煜 关俊涛 陈畅宇 孟凡伟 张辰源 李志远 魏永利 朱铭浩 肖斌数字孪生作为实现数字化转型和促进智能化升级的重要使能途径,一直备受各行各业关注,已从理论研究走向了实际应用阶段。数字孪生是以多维虚拟模型和融合数据双驱动,通过虚实闭环交互,来实现监控、仿真、预测、优化等实际功能服务和应用需求,其中数字孪生模型构建是实现数字孪生落地应用的前提。

renhongxia1的博客 1万+

More Exceptional C++中文版试读(异常安全议题及技术)

[Herb Sutter 的名作More Exceptional C++中文版即将出版。作为本书译者,我很高兴将本书推荐给大家。征得华中科技大学出版社同意,我将公开部分译稿,敬请大家批评指正。]     异常安全议题及技术   在现代C++程序设计中,对异常安全(exception safety)议题一无所知却想写出健壮的代码,这无异于痴人说梦。的确如此。 

lostmouse的专栏 1644

医学影像处理实战:用SimpleITK将CT数据重采样到统一尺寸(附完整代码)

本文针对医学影像分析中多源CT数据尺寸不一致导致深度学习模型训练失败的问题,提供了基于SimpleITK的实战解决方案。通过深入解析图像尺寸与间距的关系,详细阐述了如何通过调整体素间距进行重采样,而非简单补零,从而在保持图像物理尺寸不变的前提下,将数据统一到固定尺寸,确保输入网络的3D数据空间对齐且解剖信息准确。

weixin_29062671的博客 271

More Exceptional C++起步于Exceptional C++驻足之处

古希腊哲学家苏格拉底通过向学生提问进行教学——他用那些精心构思的问题来指导学生,启发他们从已知得出结论;让他们认识到自己正在学习的事物如何相互联系,这些事物与他们已有的知识又如何联系。这种教学法如此出名,以致于我们今天把它专称为“苏格拉底问答法”。如果让我们也从学生的角度来看问题,苏格拉底的教学法将引导我们,促使我们思考,帮助我们联系并应用现有的知识去获取新知。 本书如同它的前任Exceptional C++ [Sutter00]一样,借鉴了苏格拉底的教学法。它假设你目前正身处C++产品软件开发的某个领域

博文视点(北京)官方博客 1339

Vivado FFT IP核配置与实战:FPGA信号处理硬件加速指南

快速傅里叶变换(FFT)是数字信号处理(DSP)中的核心算法,用于将时域信号转换到频域进行分析。其原理基于离散傅里叶变换(DFT),通过蝶形运算的分解与复用,大幅降低了计算复杂度。在工程实践中,软件实现的FFT难以满足高速实时处理的需求,因此硬件加速方案至关重要。FPGA凭借其并行架构和可定制性,成为实现高性能FFT的理想平台。通过集成专用的FFT IP核,如Vivado中的Pipelined Streaming I/O架构,可以构建流水线化的计算引擎,实现极低延迟和高吞吐量的连续数据流处理。这种硬件方案特

weixin_42536863的博客 649

波分复用技术原理

波分复用原理 把不同波长的光信号复用到同一根光纤中进行传送,这种方式我们把它叫做波分复用( Wavelength Division Multiplexing ) 一根光纤被划分为多个波道,多个波长以一定的间隔隔开,在光纤中独立传输。 波分复用应用演示 如果将WDM系统看作交通系统,光纤可以看作是多个车道的公用道路。 各种类型的业务就像货物一样,被打包装载到车辆中。 车辆按照分配的车道行驶至目的地,完成货物的运输。 想要提高波分复用系统的传输容量,就要增加波道数量或是提升单波传...

m0_63251770的博客 9999

C++ 为何如此强大?

在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup,该门语言则命名为——C with classes,四年后改称为C++。

weixin_53644828的博客 289

多模态对齐方案

本文中我们介绍了 13 中常见的大型多模态模型(Large Multimodal Models, LMM),包括 BLIP-2,LLaVA、MiniGPT、Qwen-VL 以及 Ferret 等。最全 LMM 模型结构(13种)综述。单层linear投影、两层mlp。

liguandong 2083

读书笔记之:More Exceptional C++ (2002) [++]

1. std::cin和std::cout的类型是什么? 简单的回答,cin实际上是: std::basic_istream<char,std::char_traits<char>> cout实际上是: std::basic_ostream<char,std::char_traits<char>> 首先,cin和cout具有的类型...

weixin_33957648的博客 129

PentAGI自动渗透测试平台搭建与使用

但是PentAGI的缺陷也比较明显,一个是自动化程度高带来过程的介入困难,整个渗透的过程都交给AI自动决策,无法进行人工调整,耗时较长;从上述过程来看PentAGI似乎是一个比较“可用”的AI自动化渗透测试平台,但是在继续等待测试的过程中,PentAGI的一些缺点也暴露了出来,一个是测试的过程非常漫长,因为PentAGI是使用配置大模型API key的方式全自动运行,支持openai、deepseek等主流LLM大模型,过程中不需要人工介入,会不断自动调整,所以比较依赖于大模型本身的响应速度。

墨痕诉清风的博客 2415

通信原理 | 窗函数 | 矩形窗 | 汉宁窗 | 汉明窗 | 布莱克曼窗 | 补零对频谱的影响

比如,原信号是一个周期的余弦信号,又给它补了9个周期长度的0,那么信号并不是10个周期的余弦信号,而是一个周期的余弦加一串0,补零并没有带来新的信息!频谱分辨率的含义是两个频率不同的信号在频率上可分,也就要求他们不能落到一个频域函数的主瓣上,所以,如果待分析的两个信号频率接近,而时域长度又短,那么在频域上他们就落在一个频域函数的主瓣内了,补再多的零也无济于事。而形状(主瓣宽度)是由补零之前的信号长度决定的,补零的作用只是细化了频域序列,并没有改变其主瓣宽度。所以,汉宁窗牺牲了分辨率,换来了旁瓣泄露的减小。

若北辰 1305

合上More Exceptional C++的瞬间

与大师面对面(译序) 小提琴家穆特录制过一张唱片,收录的是贝多芬最伟大的两部小提琴作品 。聆听那张唱片,你仿佛听见贝多芬在向你倾诉他对音乐艺术的理解和感悟,为你解答小提琴音乐创作的每一个疑问和困惑。为了向音乐爱好者推荐贝多芬的那两部名作,穆特为她的那张名碟加上了一个恰如其分的标题—— “与贝多芬面对面”。 合上More Exceptional C++的瞬间,我的第一反应是为这本名著也加上一个与之类似的副标题,然后,郑重地推荐给你。 是的,本书奉献给你的是又一位大师苦心孤诣的结晶。不同的是,这位大师来自

博文视点(北京)官方博客 1404

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

记下最近看Exceptional C++的一些感受和疑问

1.苦于平时使用标准模板库的时间不多,对标准模板库的经验很少,所以还没有什么太多的感受不过不论是哪本关于C++标准库的书籍,都会强调一定不能使用无效的迭代器以及某些操作过后会使得迭代器失效! 2.实现大小写不敏感字符串的方法中继承了char_traitstraits的概念还是没有完全掌握,或者说应该抽时间实作一下才能更好理解 3.因为C++程序员总是把效率挂在嘴边,总是为了效率

侯杰 的专栏 1252

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: More Exceptional C++中文版试读(优化与性能)
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值