zoukankan      html  css  js  c++  java
  • Effective C++学习笔记(一)

    条款一 C++是一个语言联邦

    建议

    • c++是有兄弟的:C,Object-Oriented c++(c with class),template c++,STL
    • c++高效编程守则视状况而变化,取决于你使用c++的哪一部分。

    条款二 尽量使用const, enum, inline代替define。

    • 宁可编译器替换预处理器比较好。因为define不被视为语言的一部分。

      define NUM 3
      

      define在预处理器中已经替换成为具体的值,当编译遇到一个常量错误的时候,你可能会感到困惑,因为错误信息提到的可能是3,而不是NUM。
      而且当NUM的定义不是你所设计的时候,你可能会因为去查找3这个值所引发的错误到底是为什么而头大!这个问题也可能出现在记号调试器(symbolic debugger)中,原因相同:你所使用的名称可能并未进入记号表(symbol table)
      另一个原因是:const可以成为作用域中的一个成员,define并不能行,且不能提供任何封装性。
      还有一个原因是#define的函数

      #define MAX(a,b) func((a)>(b)?(a):(b))
      int a=5,b=0;
      MAX(++a,b);		     //a被累加二次
      MAX(++a,b+10);	    //a被累加一次
      

      在这里,调用f之前,a的递增次数不定!
      建议用内联模板

    建议

    • 对于单纯常量,最好以const对象或者enum替换#define
    • 对于形似函数的宏,最好改用inline函数替换

    条款三 尽量使用const。

    • const在常量中的运用。

      char greet[] = "hello";
      const char* p = greet; //const data,non-const pointer;
      char* const p = greet; //non-const data,const pointer;
      const char* const p = greet; //const data,const pointer;
      

      迭代器中:

      vector<int>vec;
      const vector<int>::iterator iter = vec.begin();
      *iter = 10;		 //没问题,改变iter所指的实体;
      ++iter;          //错误!iter是const
      
      //其实看过const_iterator的实现就知道,他就是对实体对象的一个const
      vector<int>::const_iterator citer = vec.begin();
      *citer = 10;		 //错误!*citer是const;
      ++citer;            //没问题!改变citer
      
    • const在函数中的运用

      const Rational operator*(const Rational &lhs);

      避免用户XJBY。

    • const成员函数

      第一,他们使得class接口比较容易理解,可以知道哪个函数可以改动对象内容,哪个函数不行。
      第二,他们使得“操作const对象”成为可能。

    • 编译器强制实施bitwise constness,但你编写程序时应该使用概念上的常量性

    • 当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复。但是要做好类型转换,否则会出现自己调用自己的现象。

      const char& operator[] (int position) const
      {
          return m_text[position];
      }
      
      /*  返回类型是个reference to char,不是char  */
      char &operator[](int position)
      {
          return m_text[position];
          /*调用const operator[]*/
          /*
          return const_cast<cahr&>(const TextBlock&)(*this)[position]);
          */
      }
      

    建议

    • const真的是一个磨人的小妖精

    条款四 确定对象在使用前已经初始化。

    • 为内置型对象进行手工初始化,因为C++不保证初始化它们。

    • 构造函数最好使用成员初始化列表(member initialization list),而不要在构造函数本体内使用赋值操作(assignment)。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
      C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前。构造函数体内的“=”叫做“赋值”,初始化发生的时间更早,发生于这些成员的default构造函数被自动调用之时。
      赋值构造的实质是:先设定初值,再为它们赋予新值。
      成员列表初始化:避免上述问题,同时避免调用copy构造函数,高效很多

    • 为免除“跨编译单元之初始化次序”问题,请以local static对象替换non-local static对象。(不是很明白)

    建议

    • 记得初始化!
    • 可以使用初始化列表
  • 相关阅读:
    闭包问题
    二级联动多选器
    一个和与后台数据连接的模板get post put 以及延伸的query
    鼠标经过图片的小动画
    UITableViewCell中cell重用机制导致内容重复的方法
    iOS Button在ios6的系统上无法实现点击,在更高版本的系统上可以
    iOS 使用Reachability实时检测网络连接状况
    iOS Uibutton防止多按钮同时按下
    iOS plist文件的添加
    iOS Xcode cannot run using the selected device.
  • 原文地址:https://www.cnblogs.com/whutao/p/10845313.html
Copyright © 2011-2022 走看看