码迷,mamicode.com
首页 > 编程语言 > 详细

Google C++ style guide——C++类

时间:2020-07-16 12:09:26      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:ini   对象   interface   报告   添加   操作符   赋值函数   程序   typename   

  1.构造函数的职责
  
  构造函数中只进行那些没有实际意义的初始化,因为成员变量的“有意义”的值大多不在构造函数中确定。
  
  可以的话,使用Init()方法集中初始化为有意义的数据。
  
  优点:排版方便,无需担心类是否初始化。
  
  缺点:
  
  1)在构造函数中不易报告错误,不能使用异常;
  
  2)操作失败会造成对象初始化失败,引起不确定状态;
  
  3)构造函数内调用虚函数,调用不会派发到子类实现中,即使当前没有子类化实现,将来仍是隐患;
  
  4)如果有人创建该类型的全局变量,构造函数将在main()之前被调用,有可能破坏构造函数中暗含的假设条件。
  
  如果,对象需要有意义的初始化,考虑使用另外的Init()方法并(或)增加一个成员标记来指示对象是否已经初始化。
  
  2.默认构造函数
  
  当一个类有成员变量又没有构造函数的时候,需要定义一个默认的构造函数,否则编译器将会自动生成默认构造函数。
  
  默认构造函数更适合于初始化对象,使对象内部状态一致、有效。
  
  编译器生成的构造函数并不会对对象进行初始化。
  
  如果你定义的类继承现有类,而你又没有增加信的成员变量,则不需要为新类定义默认构造函数。
  
  3.明确的构造函数
  
  对单参数构造函数使用C++关键字explicit。
  
  通常,只有一个参数的构造函数可被用于转换。
  
  例如:定义了Foo::Foo(string name)跟void FooTest(Foo foo)
  
  这个时候FooTest需要的是一个Foo对象作为参数,如果你传入的是string类型的参数的话,构造函数Foo::Foo(string name)将被调用,
  
  并且将该字符串转换为一个Foo临时对象传给FooTest。
  
  为避免构造函数被调用造成隐士转换,可以将其声明为explicit。
  
  所有单参数构造函数必须是明确的。在类定义中,将关键字explicit夹到单参数构造函数前。
  
  例外:在少数情况下,拷贝构造函数可以不声明为explicit;特意作为其他类的透明包装器的类。类似情况应在注释中明确说明。
  
  4.拷贝构造函数
  
  仅在代码中需要拷贝一个类对象的时候使用拷贝构造函数;不需要拷贝时应使用DISALLOW_COPY_AND_ASSIGN。
  
  大量的类并不需要可拷贝,也不需要一个拷贝构造函数或赋值操作。
  
  但如果你不主动声明它们,编译器会为你自动生成,而且是public的。
  
  可以考虑在类的private中添加空的拷贝构造函数和赋值操作,只有声明,没有定义。
  
  为了方便,可以使用宏DISALLOW_COPY_AND_ASSIGN。
  
  //禁止使用拷贝构造函数和赋值操作的宏
  
  //应在类的private:中使用
  
  #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  
  TypeName(const TypeName&);//拷贝构造函数 \
  
  void operator=(const TypeName&)//赋值操作函数
  
  class Foo {
  
  public:
  
  Foo(int f);
  
  ~Foo();
  
  private:
  
  DISALLOW_COPY_AND_ASSIGN(Foo);
  
  };
  
  绝大多数情况下都应该使用DISALLOW_COPY_AND_ASSIGN,如果类确实需要可拷贝,应该在类的头文件中说明原有,并适当定义拷贝构造函数和赋值操作。
  
  5.结构体和类
  
  仅当只有数据时使用struct,其他一概使用class。
  
  如果与STL结合,对于仿函数和特性可以不用class而是使用struct。
  
  注意:类和结构体的成员变量使用不同的命名规则。
  
  类的成员变量以下划线(_)结尾,结构体与普通变量一样,都是小写。
  
  6.继承
  
  使用组合通常比使用继承更适宜,如果使用继承的话,只使用公共继承。
  
  C++实践中,继承主要用于两种场合:实现继承,子类继承父类的实现代码;接口继承,子类仅继承父类的方法名称。
  
  如果该类具有虚函数,其析构函数应该为虚函数。
  
  限定仅在子类访问的成员函数为protected,需要注意的是数据成员应始终为私有。
  
  7.多重继承
  
  真正需要用到多重实现继承的时候非常少,只有当最多一个基类中含有实现,其他基类都是以Interface为后缀的纯借口类时才会使用多重继承。
  
  只有当所有超类除第一个外都是纯接口时才能使用多重继承,为确保它们是纯接口,这些类必须以Interface为后缀。
  
  8.接口
  
  当一个类满足以下要求时,称之为纯接口:
  
  1)只有纯虚函数和静态函数(析构函数除外);
  
  2)没有非静态数据成员;
  
  3)没有定义任何构造函数,如果有,也不含参数,并且为protected;
  
  4)如果是子类,也只能继承满足上述条件以Interface为后缀的类。
  
  9.操作符重载
  
  除少数特定环境外,不要重载操作符。
  
  一般不要重载操作符,尤其是赋值操作(opeartor =)比较阴险,应避免重载。
  
  如果需要的话,可以定义类似Equals(),CopyFrom()等函数。
  
  10.存取控制
  
  将数据成员私有化,并提供相关存取函数。
  
  如定义变量foo_以及取值函数foo()、赋值函数set_foo()。
  
  11.声明次序
  
  在类中使用特定的声明次序:public在private之前,成员函数在数据成员前。
  
  定义次序如下:public、protected、private。
  
  每一块中,声明次序一般如下:
  
  1)typedefs和enums;
  
  2)常量;
  
  3)构造函数;
  
  4)析构函数;
  
  5)成员函数,含静态成员函数;
  
  6)数据成员,含静态数据成员。
  
  宏DISALLOW_COPY_AND_ASSIGN至于private块之后,作为类的最后部分。
  
  12.编写短小函数
  
  倾向于选择短小、凝练的函数。
  
  长函数有时是恰当的,因此对于函数长度并没有严格限制。
  
  如果函数超过40行,可以考虑在不影响程序结构的情况下将其分割一下。

Google C++ style guide——C++类

标签:ini   对象   interface   报告   添加   操作符   赋值函数   程序   typename   

原文地址:https://www.cnblogs.com/dfr598/p/13314954.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!