编码规范

实际开发中应该严格按照此规范执行,也可以作为代码review参考点,下面列表有好的习惯,也有必须执行的编码行为,好的习惯字体颜色为绿色必须执行的规范字体颜色为红色

  1. 子类重写基类函数时,函数声明后面一定增加override关键字

    具体原因参考这篇文章

  2. 虚函数的参数不能有缺省值
  3. 禁止在构造、析构函数内调用virtual函数

    base class构造期间virtual函数绝不会下降到derived class,virtual函数不是virtual函数,base class构造函数的执行早于derived class构造函数,那么 当base class构造函数执行时derived class的成员变量尚未初始化,如果base class构造期间调用virtual函数下降到derived class,而derived class重写的virtual函数很有可能会使用成员变量, 那么此时derived class成员变量还尚未初始化

    根本原因是在derived class对象的base class构造期间,对象的类型是base class而不是derived class。不只virtual函数会被编译器解析为base class,如果使用运行期类型信息,也会把对象视为base class 类型,这样做也是为了防止上面提到的未初始化错误

    derived class对象在derived class的构造函数开始执行前不会成为一个derived class对象,base class的构造函数总是在derived class的构造函数开始执行前而执行

    析构函数也是同样的道理,析构函数的执行顺序是先derived class后base class,进入base class析构函数后对象就成为一个base class对象,virtual函数会被编译器解析为base class

    如果非要在构造期间调用成员函数,那么可以编写这个class的工厂函数,当构造完成时再调用成员函数,例如:

     std::shared_ptr<Widget> MakeWidget()
     {
         auto&& ptr = std::make_shared<Widget>();
         ptr->MemberFunc();
         return ptr;
     }
    
  4. 尽量使用初始化列表,并且按照声明顺序
  5. 禁止对有虚函数的类使用memset
  6. 非void返回值函数必须有返回值

    如果没有返回值,那么外层调用函数在使用函数返回值时在栈内相邻位置取到的值是未知的

  7. 一定要将监听套接字设置为非阻塞的

    更多细节参考这篇文章