华为C++语言编程规范
华为C++语言编程规范,内部资料se语言编程规范内部公开目录0说明前言代码总体原则与语言编程规范的关系规范实施、解释术语定义1常量62初始化和类型转换声明、定义与初始化类型转换3函数12内联函数函数参数函数指针4类...14类的设计构造、赋值和析构继承重载5作用域、模板和C+其他特性..25作用域模板其他6资源分配和释放287异常与错误处理33异常错误处理策略8标准库369程序效率语言特性的性能分级语言的性能优化指导华为机密,未经许可不得扩散第页共页se语言编程规范内部公开0并发4511风格48标小符命名与定义排版注释文件组织12可移植性(兼容性).4913全球化52多语言输入输出单一版本时区夏令时14业界编程规范和书籍55业界编程规编程指南《编程规范条规则、准则与最佳实践》《微软一站式示例代码库》扩展学习材料华为机密,未经许可不得扩散第页共页se语言编程规范内部公开语言编程规范0说明前言随着业务的发展和产品架构的演进,越来越多的传统电信产品使用C++语言,很多新型产品更是把C+作为首选。C艹继承于C,包含C的所有特性,同时又增加了新语言特性,如面向对象、泛型设计等。目前C-+使用现状是:基础技能薄弱,陷入很多误区,不能很好地发挥C++的作用。为了帮助团队合理使用C-+,规避语言陷阱,特制定本规范代码总体原则毘C语言编稈一样,C++编稈遵循通用原则:1、清晰第一。清晰性是易于维护、易于重构的程序必需只备的特征。2、简洁为美。简洁就是易于理解并且易于实现。3、选择合适的风格,与代码原有风格俣持一致。除此之外,C+编程还应该注意以下方面1、正确使用C+面向对象技术使得程序结枃清晰、简单,提高了代码的重用性,但又隐藏了很多內部实现细节,内存模型复杂,不小心会误入陷阱,比如:拷贝构造函数,赋值操作符,析构函数,重载等为了简化代码,改善代码结构,提髙编程效率,一些团队引入新特性和第三方库,如:模板技术、STL、Bost等,由于缺乏足够的理解,使用中屡次发生问题,比如对达代器( Iterator)使用不当导致功能失常,甚至稈序崩溃。所以,必须深入理解C艹+对象布局、內存模型等,了解编译器背后所做的处理,才能在编程中知道如何止确使用2、安全高效跟其他流行的高级语言、脚本语言相比,C艹+运行速度快,天然适合开发核心通信部件,但是这些部件对稳定性的要求非常高,不容许发生异常、失效以及崩溃。C艹-具有直接操作硬件、访问內存的能力提供了指针、地址运算等灵活特性,稈序员可以仟意发挥,增加了出锖的几率。所以在追求速度与灵峾性的冋同时,一定要注意保持程序的健壮性。在増强代码稳定性过桯中,程序员通常采用i-else等防御式编程,使得代码非常臃肿,可适当采用RAIⅠ、智能指针等技术华为机密,未经许可不得扩散第页共页se语言编程规范内部公开与语言编程规范的关系本文在《华为技术有限公司C语言编程规范》(简称C规范)基础上,通过详细阐述如何规避C++语言复杂性,避免C+-的低级错误,确保有效使用C-+语言特性,代码易于维扩。C规范里面相同的内容,夲规范不再重复。例如头文伻、变量、表达式、代码编辑与编译、可测试性安全性、单元测试等章节经过审妉,完全适合C+,本规范不再重复。标识符命名与定义、注祥、排版与柊式等内容也适合C++,仅仅添加了少量的C+特有的规则和建议,合并成风格一章;涵数章节增加了內联函数、函数参数等内容;可移植性増加了64位以及C艹+专冇的薮据转换等內容;质量保证也符合C艹+的需要,将资源分配和释放部分C艹特有的内容编写成单独章节;宏、常量也符合C++,考虑到C++普遍使用 cons t,增加了常属性( const)章节。新増初始化和类型转换,类,作用域、模板与C艹-其他特性,异常与错误处理,并发,全球化等C艹特有的内容本规范和C规范有沖突的地方,以本规范为准。规范实施、解释本规范制定了编写C+语言程序的基本原则、规则和建议。木规范适用于公司内使用C++语言编码的所有软件。本规范自发布之日起生效,对以后新编写的和修改的代码应遵守本规范本规范由软件工稈体系发布和维护。实施屮遇到问题,可以到论坛http://hi3ms.huaweicom/group/1735/threads.htmi上讨论。在某些情况下需要违反本规范给出的规则时,相关团队必须通过一个正式的沇程来评审、决貪规则违反的部分,个体程序员不得违反本规范中的相关规则。术语定义原则:编程时必须坚持的指导思想规则:编程时强制必须遵守的约定。建议:编程时必效加以考虑的约定说明:对此原则/规则/建议进行必要的解释。示例:对此原则/规则/建议从好、不好两个方面给出例子。延伸阅读材料:建议进一步阅读的参考材料。常量不变的值更易于理餡、跟踪和分析,所以应该尽可能地使用常量代替变量,定义值的时侯,应该把 const作为默认的选项规则1.1使用 const常量取代宏华为机密,未经许可不得扩散第页共页se语言编程规范内部公开说明:宏是简单的文本替换,在预处理阶段时完成,运行报错时直接报相应的值;跟踪调试时也是显示值,而不是宏名;宏没有类型检查,不安全;宏没有作用域。示例defi: e MAX MSISDN LEN(20)//不好的例子const int MAX MSISDN LEN=20;/好的例子规则1.2一组相关的整型常量应定义为枚举说明:之所以使用枚举,基于:●枚举比# define或 const int更安全,因为编译器会检查参数值是否是否位于枚举取值范围内,从而避免错误发生。示例//好的例子enum DayofWeek( sunday, monday, tuesday, wednesday, thursday, friday, saturday)ienum Ccloriblack, blue, whiter red, purp_e]BOOL CclorizeCalendar (DayofWeek today, Color todays Color)Coorizeca1 endor(b1ue, sunday);//编译报错,1ue和 Sunday位置错误//不好的例子:const int sunday=0iconst int monday= 1const int b⊥acKconst int blueBOOL CclorizeCalendar (int today, int todays ColorCoorizecalendar(blue, sunday);//不会报错当枚举值需要对应到具体数值时,须在声明时昰示赋值。否则不需要昰式赋值,以避免重复赋值,降低维护(增加、朋除成员)工作量示例好的例子:s协议里定义的设备I值,用于标识设备类型cnum TDcv-cclypcDEV UNKNOWN --l,DEV DSMP 0DEV工SMGDEV WAPPORTAL=2程序内部使用,仅用于分类的情況,不应该进行显式的赋值。示例/好的例子:程序中用来标识会话状态的枚举定义enum TSessionstateSESSION STATE INITISESSTON STATE CTOSEDSESSION STATE WA工TING●应当尽量避免枚举值亘复,如必须重复也要用己定义的枚举来修饰,例如:typed f enumRTCP SR 200,RTCP MIN TYPE RTCP SR//must be lowest known typeRTCP RR华为机密,未经许可不得扩散第页共页se语言编程规范内部公开RTCP SDES= 202RTCP BYE203,RTCP APP204,RTCP RTPFB=205RTCP PSEB =206/RTCP XR207RTCP RSI =208RTCP PUBPCRTS =209RTCP MAX TYPF= RTCP PUB PORTS //must be highest known typertcp type ti规则1.3不相关的常量,即使取值一样,也必须分别定义说明:一个常量只用来表示一个特定功能,即一个常量不能有多种用途。示例:/好的例子:协议和协议B,于机号( (MSISDN)的长度都是20。unsigned const int. A MAX MST SDN LEN0;unsigned const int B MAX MSI SDN LEN 20//或者使用不同的名字空间namespace alibunsigned const int MAX MSISDN LEN=20;namespace blibunsigned const int MAX MSISDN LEN =20建议1.1尽可能使用 const说明:在声明的变量或参数前加上关键字 const用于指明变量值不可被篡改。类成员函数加上 const限定符表明该函数不会修改类成员变量的状态使用 const常见的场景:函数参数:传递引用时,如果函数不会修改传入参数,该形参应声明为 const。成员函数:访问函数(如get函数):不修改任何数据成员的函数:未调用非 cons t函数、未返回数据成员的非 const指针或引用的函数。数据成员:如果数据成员在对象构造之后个再发生变化,可将其定义为 cons t。2初始化和类型转换声明、定义与初始化规则2.1禁止用 memcpy、 memset初始化非POD对象说明:PO全称是“ Plain0 ld Data”,是C++98标准(ISO/IEC14882, first edition,19980901)中引入的一个概念,POD类型主要包括int,char, float, double, enumeration,woid,指针等原始类型及其集合类型,不能使用封装和面对对象特性(如用户定义的构造/赋值/析构函数、基类、虚函数等)。华为机密,未经许可不得扩散第页共页se语言编程规范内部公开由于非P0D类型比如非集合类型的 class对象,可能存在虚函数,内存布局不确定,跟编译器有关,滥用内存拷贝可能会导致严重的问题即使对集合类型的 class,使用直接的内存拷贝和比较,破坏了信息隐蔽和数据保护的作用,也不提倡memcpy、 memset操作示例:×××产品程序异常退出( corc dump)。经过现场环境的模似,程序产生 COREDUMP,其原因是:在初始化函数内使用 memset(this,0,sizeof(*this))进行了类的初始化,将类的虚函数表指针被清空,从而导致使用空指针。解决方案:使用C艹构造函数初始化,不要便用 memset函数初始化类对象建议2.1变量使用时才声明并初始化说明:变量在使用前未赋初值,是常见的低级编程错误。使用前才声明变量并同时初始化,非常方便地避免了此类低级错误。在函数开始位置声明所有变量,后面才使用变量,作用域覆盖整个函数实现,容易导致如下问题:程序难以理解和维护:变量的定义与使用分离变量难以合理初始化:在函数丌始时,经常没有足够的笮息进行变量初始化,往往用某个默认的空值(比如零)来初始化,这遥常是一种浪费,如果变量在被赋于有效值以前使用,还会导致错误。遵循变量作用域最小化原则与魷近声明原则,使得代码更容易阅读,方便了解变量的类型和初始值特别是,应使用初始化的方式替代声明再赋值示例:不好的例子:声明与初始化分离string name;//声明时未初始化:调用缺省构造函数nane=" zhangsan";//再次调用赋值操作符函数;声明与定义在不同的地方,理解相对困难好的例子:声明与初始化一体,理解相对容易string name(" zhangsan");//调用一次构造函数建议2.2避免构造函数做复杂的初始化,可以使用“init”函数说明:正如函数的变量都在函数内部初始化一样,类数据成员最好的初始化场所就是构造函数,数据成员都应该尽量在构造函数中初始化以下情况可以使用init(函数来初始化:需要提供初始化返回信息。数据成员初始化可能抛异常。●数据成员初始化大败会造成该类对象初始化失败,引起不确定状态数据成员初始化依赖this揞针:构造凶数没结束,对象就没有构造出来,构造凶数內不能使用this成员数据成员初始化需要调用虚函数。在构造函数和析构函数中调用虚函数,会导致未定乂的行为示例:数据成员初始化可能拋异常:cl ass CPPRule华为机密,未经许可不得扩散第页共页se语言编程规范内部公开publicCEPRule(): size (0), res (null)i//仅进行值初始化long init (int size)//根据传入的参数初始化size,分配资源resr vateint siResourceptrx res//使用方法CPPRule ait(100)建议2.3初始化列表要严格按照成员声明顺序来初始化它们说明:编译器会按照数据成员在类定义中声明的顺序进行初始化,而不是按照初始化列表中的顺序,如果打乱初始化列表的顺序实际上不起作用,但会造成阅读和理解上的混淆;特别是成员变量之间存在依赖关系时可能导致BUG示例://不好的例子:初始化顺序与声明顺序不一致class Emp-oyeepublic:Employee(const charx firstName, const charx lastNamefirstName (firstName), lastName (lastName)r email (firstName.+-astName t huawei. com)ipr-vate:string email, firstName lastName类定义emai1是在 firstName, lastName之前声明,它将首先初始化,但使用了未初始化的ratNam和 lastName,导致错误。在成员声明时,应按照成员相互依赖关系按顺序声明。建议2.4明确有外部依赖关系的全局与静态对象的初始化顺序说明:如果全尻对象A的成员变量有外部依赖,比如依赖另外一个全局变量B,在A的构造函数中访问B,隐含的规则就是B先于A初始化,然而全局与静态对象的初始化与析构顺序未有严格定义,无法确保B已经完成初始化,而每次生成可执行程序都可能发生变化,这类BUG难以定位。通常采用单件( Singleton)模式或者把有依赖关系的全局对象放在一个文件中定义来明确初始化顺序冋一个文件屮,若全局对象a在全局对象b之前定义,则a一定会在b之前初始化;但是不同文件中的全局对象就没有固定的初始化顺序。可以在main0或 pthread once(内初始化一个运行期间不回收的指针类型转换避免使用类型分支来定制行为:类型分支来定制行为容易出错,是企图用C+编写C代码的明显标志。这是一种很不灵活的技术,要添加新类型时,如果忘记修改所有分支,编译器也不会告知。使用模板和虚函数,让类型自己而不是调用它们的代码来决定行为。华为机密,未经许可不得扩散第页共页
- 2020-12-12下载
- 积分:1
语音信号处理中基频提取算法综述
语音信号处理中基频提取算法综述,论述了各种基频检测的算法,对比分析各方法与思想,不错的总结增刊张杰等:语音信号处理中基频提取算法综述101信号是由频率具有谐波关系的信号组成的,因此有的一个改进是采用多分辩率方法。该方法的思想是:很多尝试利用频域信息提取基频的方法如果一个特定算法在特定分辨率下的准确性是可疑21基于滤波器的算法的,那么采用更高或者更低的分辨率,可以进一步21.1最佳梳状滤波器法判断前面的基频估计是否可信。如果在全部或人部最仹梳状滤波器法閃是具有高鲁棒性但计算代分的分辨率下求得相同的基频,那么该频率值就可价很大的算法。一个梳状滤波器有很多等距离分布以作为最终的基频估计结果。当然,在带来好处的的通带,在最佳梳状滤波器算法中,通带的位置都同时,该方法也会带来计算量上的代价,因为针对是由第一个迸带决定的,即通带的中心频率都是第每个分辨率都需要重新计算频谱,这也是为什么一个通带中心频率的整数倍。输入信号通过多个与多分辨率的傳里叶分析比专门的多分辨率变换(如第一个通带中心频率不同的梳状滤波器。如果输入离散小波变換)要慢的原因信号是由一组频率成谐波关系的信号组成的,那么2.4离散小波变换法滤波器的输出在全部谐波成分都通过滤波器时达到离散小波变换是一个强大的工具,它允许在连最大。但是如果信号只有一个基频成分,该方法就续的尺度上把信号分解为高频成分和低频成分,它会失效,因为会有很多个梳状滤波器能让信号通过。是时间和频率的局部变换,能有效地从信号中提取不过,语音信号的频率具有谐波结构,所以可采用信息。与快速傅里叶变换相比,离散小波变换的主该方法提取基频。要好处在于,在髙频部分它可以取得好的时间分辨2.1.2可调的IR滤波器率,在低频部分可以取得好的频率分辨率。文献四提出了一种基于中心频率可调节的带通3统计的方法IR滤波器提取棊频的方法,随着用户的调节,滤波器的中心频率扫过整个频域。当输入信号的一个强在某种意义上,基频提取的问题可以被看作是的频率成分在通带沱围内时,滤波器会输出最大值,个统计问题。每一个输入帧都被划分给一组类中信号的基频就可以用此时滤波器的中心频率来估的一个,代表信号的基频估计。所以很多研究者计。文献[9提到,对于可调的I滤波器,有经验的直试图将现代的统计方法应用于基频提取问题用户能够识别只有一个谐波结构的信号的输出和包Boris和 Xavier发表了一系列使用最人似然法估含多个基频信号的输出的差异计基频的方法。他们的模型如卜:观察集是语音信2.2倒谱分析法号分帧后做短时傅里叶变换的结果,每一个观察都倒谱分析是谱分析的一种方法,翰出是傅里叶被看作是基频激励产生的信号与其他剩余信息(包变换的幅度谱取对数后做傅里叶逆变换的结果。该括非谐波部分和噪声)两部分的混合。该模型是由方法所依据的理论是,一个具有基频的信号的傅立般的语音信号产生的模型的简单化得到的,假没叶变换的幅度谱有一些等距离分布的峰值,代表信个语音包括在基频及其整数倍点的值处较大的谐波号中的谐波结构,当对幅度谱取对数之后,这些峰成分,以及在非谐波处和噪声处的很小的值。对于值被削弱到一个可用的范围。幅度谱取对数后得到一组候选的基频值,该方法计算每一个观察可能是的结果是在频域的一个周期信号,而这个频域信号由某一个基频产生的概率,并将概率最大的基频值的周期(是频率值)可以认为就是原始信号的基频,所作为最终的估计值。所以候选的基频值的选择是很以对这个信号做傅里叶逆变换就可以在原始信号的重要的,因为从理论上讲,观察可能对应着任意的基音周期处得到一个峰值基频值。另妒,如果对信号的傅里叶变换的嘔度谱取对数后的结果直接进行分析,而不是雨接着做傅里叶4算法的改进逆变换,就是谐波成分谱的方法。进一步,如果在前面提到的每种算法都有自己的改进方法,下求频域的变换时不使用傅里叶变换,而使用能使频面介绍两种对以上大部分算法均适用的改进方法。谱更加精细的Chip变换,就是基」Chi变换的提取41人的听觉模型基频的方法,该方法具有高分辨率和高鲁棒性。由于基频提取本身就是听觉感知问题,所以所23多分辨率的方法有的算法都可通过加入人耳的听觉模型提扃性能对于任何基于傅里叶分析的频域方法都可以做人耳的听觉模型将人的听觉系统对声音信号的处理102电子科技大学学报第39卷分为分析、传递和还原3个阶段。分析阶段主要考虑5经典的基频检测方法耳蜗的分频效应,耳蜗的外端对高频敏感,内端对低频敏感,可以用一组中心频率不同的带通滤波器自从有了语音信号分析饼究这门学科以来,基来模拟。传递阶段声波振动沿基膜传播,并在听觉频的检测一直是一个重点研究的课题。经典的基频神经纤维内产生电流,最终传入听觉中枢。还原阶检测方法可以大致分为3类,如表1所示段听觉系统提取语音中诸如音质、音调、时域和位表1经典的基音检测方法以及特点置等信息。分类基因检测方法特点在声学中,声强是指单位时间内通过垂直」声由多种简单的波形峂值泼传播方向的单位面积的声波能量,用表示。当声并行处理法检沏器提取基音周期波的频率在20~20000Hz(可闻频率)之间,而声强波形根据各种理沦探作,从波形中去行计法数据减少法达到一定的强度(听阈),就能被人耳感知。前人大量掉修正基音以外的数的实验测试结果表明,人耳对不同频率的声波感受讨零率法利用波形的讨零率,差眼于重复图形到相同响度时的声强是不同的。人耳对两端频段的利用语音波形的自相关函数提取自相关法声波反应较为迟钝,而对中间频段的声波反应相对基音,采用中心削波平坦欠理频谱,及其改进较为敏感采用峰值削波可以简化运算对于任意的频域方法,简单的改进是用Q值恒语音波形降低采样率斤,进行IPC分析相关定的谱变换方法代替傅里叶变换。恒的变换方法SIFT法用逆滤波器平坦处理频谱,通过预测误差处埋法计算代价更人,但更接近于人的听觉感知系统。的自相关函数恢复时间精度在决定是否使用人的听觉模型吋必须考虑两个采用平均幅度差函数(AMDF检测周期AMDF法性,也可以根据残差信号的因素:(1)基频提取的用途。如果应用的目的很简单,AMDF法行提取要求也不是太高,那么人的听觉感知因素也许不是倒谱法根据对数功率谱的傅立叶反变换很必要。(2)计算的复杂度。使用人的听觉感知模型分离频谱包络和微细结构会使计算复杂度大大增加,如果原来算法的复杂度变换法在频谱上求出基频高次谐波成分的直方已经很大,再加入人的听觉感知模型可能会使算法循环直方图法图,根据高次谐波的公约数决定某音的复杂度过高4.2基频的跟踪(1)波形估计法。直接由语音波形估计、分析波另一种对基频提取的改进是基频跟踪。前面提形上的周期峰值到的基频提取都是在个单独的时间窗内进行的。(2)相关处珄法。时域中周期信号最明显的特征人的听觉系统是能够眼踪输入信号的基频的。一个是波形的类似性,因而可以道过比较原始信号和它只包含有限个基音周期的时间窗内的基频是很难提位移后的信号之间的相似性确定基音周期。该类方取的。但是,如果输入是连续的语音信号,相当于法抗波形的相位失真能力强,且馍件处理结构简单。很多时间窗个接个输入,基频的提取反而变得3)变换法。将语音信号变換至频域或倒谱域估很容易。研究发现,语音信号的基频具有连续性,计基音周期即前后两帧的基频是连续的,不出现跳变。一帧内6总结的基频提取常见的问题是得到的佔计值是正确值的本文列出了若干基频提取的主要方法,对它们整数倍或者整数倍分之一。针对该问题,利用语音分别进行了简单的介绍,并讨论了对算法的改进。信号基频的连续性,可对基频提取算法做一个简单需要注意的是,所介绍的方法都是针对一个语音信的改进:在计算某一恢的基频时对于它前血一帧的号而言的,对于混合的语音信号的基频提取,如果基频附近的值给予更大的可能性,即一唢语音信号可以先将混合的语音信号分离丌,那么基频提取就中基频的值不可能出现崁变的情况。这就是简单的会变待很简单。同样地,在一些基于时频分析的语基频跟踪思想,并且不会在计算上增加任何复杂度。音分离算法中,如果知道了各个语音的基频,那么另外一种比较复杂的基频跟踪方法是使用隐马语吝分离也就变得很容易解决了。尔科大模型。(下转第126页)126电子科技大学学报第39卷L9 GONG L, NEEDIIAM R, YAIIALOM R Reasoning about1990 IEEE Symposium on Research in Security and privacybelief in cryptographic protocols C]/Proceedings of the Los Alamitos, CA: IEEE Computer Society Press, 1990编辑税红(上接第102页)参考文献[5 BENJAMiN K. Spectral analysis and discrimination by[ DELLER了R, PROAKIS了 G HANSEN J H Lzero-crossings[C]Proceedings of the Institute of ElectricalDiscrete-time processing of speech signals [M]. New York:and Electronics Engineers. S 1.: [ s.n. 1986: 1477-1493[6] CURTIS R. The computer music tutorial]. CambridgeMaxell McMillan. 1993MIT Press. 1996[2 FORT A, ISMAELLI A, MANFREDI C, et al. Parametric[7] DE CHEVEIGNE A, YIN H K. A fundamental frequencyd non-parametric estimation ofapplication to infant cry[]. Med Eng Phys, 1996, 18(8estimator for speech and music[J]. Journal of the AcousticalSociety of America, 2002,11(4):1917-1930[3] PARSONS T. Voice and speech processing[M]. New York[8 EARGLE J M. Music, sound and technology M. TorontoHill,1986.Van Nostrand reinhold. 19954 RABINERR L, SCIIAFERR W. Digital processing ofspeech signals. Englewood Cliffs M]. New Jersey: Prentice编辑税红Hll,1978
- 2020-12-05下载
- 积分:1