zoukankan      html  css  js  c++  java
  • Effective C++读书笔记~9 杂项讨论

    条款53:不要轻忽编译器警告

    Pay attention to compiler warnings.

    在C++,编译器作者通常对于将会发生的事情比程序员有更好的领悟。例如,下面的例子很常见:
    程序员希望以D::f重新定义virtual B::f,但其中有个错误:B::f是const成员函数,而在D中没声明。

    class B {
    public:
           virtual void f() const;
    };
    
    class D : public B {
    public:
           virtual void f();
    };
    

    编译器可能会警告:

    warning: D::f() hides virtual B::f()
    
    // MSVC 2017警告 /Wall
    “void      D::f(void)”:      成员函数不重写任何基类虚拟成员函数
    “void      B::f(void)      const”: 不重写基“B”中的虚拟成员函数;函数被隐藏
    

    如果忽略了这个警告,可能会在f中修改数据成员,从而导致非预期行为,从而产生错误。

    另外,不同的编译器有不同的警告标准。不可依赖编译器指出所有的错误。

    小结

    1)严肃对待编译器发出的警告信息。努力中编译器的最高警告等级下争取“无任何警告”的荣誉;
    2)不要过度依赖编译器的警告能力,因为不同编译器对待事情多态度并不相同。一旦移植到另一个编译器上,原本依赖的警告信息有可能消失。

    [======]

    条款54:让自己熟悉包括TR1在内的标准程序库

    Familiarize yourself with the standard library, including TR1.

    加入TR1之前,C++98的C++标准程序库主要成分:

    • STL(Standard Template Library,标准模板库),覆盖容器(containers如vector,string,map)、迭代器(iterators)、算法(algorithm如find,sort,transform)、函数对象(function objects如less,greator)、各种容器适配器(container adapter如stack、priority_queue)和函数对象适配器(function object adapters如mem_fun,not1)。
    • iostream,覆盖用户自定义缓冲功能、国际化I/O,以及预先定义好的对象cin,cout,cerr,clog。
    • 国际化支持,包括多区域(multiple activate locales)能力。像wchar_t(通常是16bits/char)和wstring(由wchar_ts组成的strings)等类型都对促进Unicode有所帮助。
    • 数值处理,包括复数模板(complex)和纯数值数组(valarray)。
    • 异常阶层体系(exception hierachy),包括base class exception及其derived class logic_error和runtime_error,以及更深继承的各个classes。
    • C89标准库程序。

    TR1详细叙述了14个新组件(components,即程序库技能单位),都放在std::tr1命名空间内。如shared_ptr全名是std::tr1::shared_ptr。主要的TR1组件包括:

    • 智能指针(smart pointers)tr1::shared_ptr和tr1::weak_ptr。前者类似于内置指针,但会记录有多少个tr1::shared_ptrs共同指向同一个对象,即所谓reference counting(引用计数)。一旦对象的引用计数为0,即这样的指针被销毁,该对象就会被自动删除。在这非环形(acyclic)数据结构中防止资源泄漏很有帮助。 tr1::weak_ptr 能有效避免环形数据结构导致的资源泄漏问题。
    • tr1::function,表示任何callable entity(可调用物,即函数或函数对象),只要签名符合目标。

    以前,当我们想注册一个callback函数,接受一个int并返回一个string的函数作为参数,可以这样写:

    void registerCallback(std::string func(int));
    // 省略参数名称
    void registerCallback(std::string (int));
    

    这里“std::string (int)”是个函数签名。

    而当我们有了tr1::function后,可以接受任何可调用物,只有它可以接受一个int或任何可以被转换为int的东西,并返回一个string或任何可以被转换为string的东西。

    void registerCallback(std::tr1::function<std::string (int)> func);
    // 参数func可以接受任何可调用物,只有其签名与“std::string (int)”一致即可
    
    • tr1::bind,参数绑定,能做STL绑定器(binders)bind1st和bind2nd所做的每件事,而且更多。

    其他TR1组件划分为2组。第1组提供彼此互不相干的独立机能:

    • Hash tables,用来实现sets,multisets,maps和multi-maps。每个新容器的接口都以其前任(TR1之前的)对应容器塑模而成。这些名称:tr1::unordered_set, tr::unordered_multiset, tr1::unordered_map以及tr1::unordered_multimap。强调它们和set,multiset,map或multimap的不同:以hash为基础的这些TR1容器内的元素并无任何可预期的次序。
    • 正则表达式(Regular expressions),包括以正则表达式为基础的字符串查找和替换,或是从某个匹配字符串得到另一个匹配字符串的逐一迭代(iteration)等。
    • Tuples(变量组),标准程序库中pair template的新一代制品。pair只能持有2个对象,tr1::tuple可持有任意个数的对象。
    • tr1::array,本质上是个“STL化”数组,即一个支持成员函数如begin和end的数组。不过,tr1::array大小固定,不使用动态内存。
    • tr1::mem_fn,语句构造上与成员函数指针(member function pointers)一致。就像bind扩充C++98的bind1st和bind2nd的能力一样,mem_fn扩充了C++98的mem_fun和mem_fun_ref的能力。
    • tr1::reference_wrapper,一个让reference的行为更像对象的设施,可以造成容器持有如reference。而容器实际上只能持有对象或指针。
    • 随机数(random number)生成工具,超越了继承自C标准库程序的函数rand。
    • 数学特殊函数,包括Laguerre(拉盖尔)多项式,Bessel( 贝塞尔)函数,完全椭圆积分(complete elliptic integrals),以及更多数学函数。
    • C99兼容扩充。这是一大堆函数和模板(template),用来将许多新C99程序库特性带进C++。

    第2组TR1组件由更精巧的template编程技术(template metapromming,模板元编程)构成:

    • Type traits,一组traits class,用于编译器萃取出类型。
    • tr1::result_of,该模板用来推导函数调用的返回类型。

    注意:TR1并未对原有组件进行修改,而是对标准库程序的纯粹添加。

    TR1本身只是一份文档,为了取得其所规范的机能,还需要取得实效代码,如使用Boost程序库,或C++11以上版本提供的标准程序库。

    小结

    1)C++标准程序库的主要机能由STL、iostream、locale(系统区域设置,即国家或地区设置)组成,并包含C99标准程序库。
    2)TR1添加了智能指针(smart_ptr,如tr1::shared_ptr)、一般化函数指针(tr1::function)、hash-based容器、正则表达式(regular expression)以及另外10个组件的支持。
    2)TR1自身只是一份规范,可以Boost程序库,或C++11标准程序库。

    [======]

    条款55:让自己熟悉Boost

    Familiarize yourself with Boost.

    Boost是一个C++开发者社群,可以自由下载其程序库,网址:https://www.boost.org/
    Boost是C++标准程序库的beta版本(先行者),很多实验成熟的库函数,会慢慢转移到标准程序库中。

    Boost程序库要对付的主题很多,主要包括:

    • 字符串与文本处理,覆盖具备类型安全(type-safe)的printf-like格式化动作、正则表达式(TR1同类机能的基础),以及语汇单元切割(tokenizing)和解析(parsing)。
    • 容器,覆盖“接口与STL相似且大小固定”的数组,大小可变的bitsets以及多维数组。
    • 函数对象和高级编程,覆盖若干被用来作为TR1机能基础的程序库,如lambda。
    • 泛型编程(Generic programming),覆盖一大组traits class(条款47)。
    • 模板元编程(template metaprogramming,TMP,条款48),覆盖一个针对编译器assertions而写的程序库以及Boost MPL程序库。MPL支持编译器实物如type的STL-like数据结构。
    • 数学和数值(Math and numberics),包括有理数、八元数和四元数、常见公约数(divisor)和少见的多重运算、随机数。
    • 正确性与测试(Correctness and testing),覆盖用来将隐式模板接口(implicit template interface,条款41)形式化的程序,以及针对“测试优先”编程形态而设计的措施。
    • 数据结构,覆盖类型安全(type-safe)的unions,以及tuple程序库。
    • 语言间的支持(inter-language support),包括允许C++和Python之间的无缝互操作性(seamless interoperability)。
    • 内存,覆盖Pool程序库,用来做出高效率而区块大小固定的分配器(条款50),以及多变化的智能指针(条款13),包括TR1智能指针。
    • 杂项,包括CRC检验、日期和时间的处理,在文件系统上来回移动等。

    注意:Boost没有提供整套编程方案,如没有针对GUI开发设计的程序库,也没有连通数据块的程序库。

    小结

    1)Boost是一个社群,也是一个网站,提供免费、源码开放、同僚复审的C++程序库开发。
    2)Boost提供许多TR1组件实现品,以及其他许多程序库。

    [======]

  • 相关阅读:
    取得窗口大小和窗口位置兼容所有浏览器的js代码
    一个简单易用的导出Excel类
    如何快速启动chrome插件
    网页表单设计案例
    Ubuntu下的打包解包
    The source file is different from when the module was built. Would you like the debugger to use it anyway?
    FFisher分布
    kalman filter
    Group delay Matlab simulate
    24位位图格式解析
  • 原文地址:https://www.cnblogs.com/fortunely/p/15666064.html
Copyright © 2011-2022 走看看