C++ Coding Standards:函数与操作符;类设计与继承

原创 2005年05月20日 17:08:00

By Herb Sutter, Andrei Alexandrescu

树人译

函数和操作符

25.      合理地对待通过传值,传(智能)指针或传引用的参数。

合理地确定参数:区分输入,输出和输入/输出参数,区分值参数和引用参数。合理地对待它们。

26.      保留被重载操作符的自然语义。

程序设计人员并不喜欢惊奇:只有在有适当的理由时采取重载操作符,而且要保留自然的语义;如果那样做很困难的话,那你可能滥用操作符重载了。

27.      优先使用算数和赋值操作符的规范形式。

如果有a+b的话,也应该有a+=b:在定义二元算数操作符时,也要提供它们对应的赋值版本,而且要使重复最小,效率最佳。

28.      优先使用++操作符的规范形式。优先调用前缀形式。

如果有++c的话,也应该有c++:由于递增和递减操作符有各自的前缀和后缀形式,而且语义也稍有不同,这样就显得它们有些棘手。定义模仿其内建副本行为的operator++operator—。如果你不需要原始值的话,优先调用前缀版本。

29.      考虑用重载来避免隐式类型转换。

不去增加需求之外的对象(奥卡的剃刀):隐式类型转换提供了语法上的便利(但参见Item40)。但是当创建临时对象的工作没有必要而且优化要适当的时候,你可以提供重载函数,它的型构与公共的参数类型精确地匹配,而且不会引起转换动作。

30.      避免去重载&&||,或,(逗号)。

贤人知道适可而止:编译器会特殊对待内建的&&||,(逗号)。如果要重载它们,它们就成了普通函数,有非常不同的语义,而且这是引入微妙的bug和脆性的一个“可靠的”途径。

31.      不要编写依赖于函数实参评估顺序的代码。

保持(评估)顺序:一个函数的实参的评估顺序没有被指定,所以不要依赖于一个特定的顺序。

类设计和继承

32.      搞清楚你正在编写的类的种类。

了解你自己:有许多不同种类的类。了解你正在编写的类的种类。

33.      优先使用最小型的类,而不是整体式的类。

分而治之:小型类更容易编写,正确,测试和使用。在多数情况下小型类更可能合用。优先使用这些包含了简单概念的小型类,而不是那些试图实现很多或者是复杂的概念的大型类(参见:Item5Item6)。

34.      优先使用组合,而不是继承。

避免承受继承的负担:在C++中继承是仅次于友元的第二紧密的耦合关系。紧耦合是不受欢迎的,而且要尽可能地避免它。因此,优先使用组合,而不是继承,除非你知道后者真正有益于你的设计。

35.  避免从那些没有被设计用来当作基类的类派生。

一些人并不想要孩子:那些被用来独立使用的类与基类相比,它们执行着不同的计划(参见Item32)。把独立的类当作基类是一种严重的设计错误,我们应该避免它。要增添行为,优先增加非成员函数,而不是成员函数(参见Item44)。要增加状态,优先使用组合,而不是继承(参见Item34)。避免从具体基类继承。

36.  优先使用抽象的接口。

热爱抽象艺术:抽象接口可以帮你集中于得到一个正确的抽象概念,而不用把它和实现或状态管理细节混在一起。优先设计这样的层次结构,它实现了对抽象概念建模的抽象接口。

37.  公有继承就是具有可替换性。继承不是重用,但可以被重用。

Know what:公有继承可以让一个指向基类的指针或引用去引用某个派生类的一个对象,而且既不会破坏代码的正确性也不需要变更既有代码。Know why:不要通过公有地继承来重用代码(也就是基类中存在的代码);共有地继承是为了被重用(通过那些已经多态地使用了基类对象的既有代码)。

38.  使用安全的改写(overriding)。

在改写一个虚拟函数时,要保持可替换性;特别地,要注意在基类中函数的前置和后置条件。不要变更虚拟函数的默认实参。优先考虑显式地把改写的函数重新声明为virtual。小心会隐藏基类中的重载函数。

39.  考虑让虚拟函数非公有,让公有函数非虚拟。

在基类中变更(特别是在程序库和框架中)的代价是非常高的:优先让公有函数非虚拟。优先让虚拟函数私有化或者(如果派生类需要有调用基类版本的能力的话)受保护。(注意这个建议对析构函数不适用;参见Item50

40.  避免提供隐式的转换。

并非所有的变更都是改进:隐式的转换经常是害大于利。在提供隐式的转换前,重新考虑一下你定义的类型,并且优先依赖于显式的转换(explicit构造函数和具名的转换函数)。

41.  让数据成员私有化,除非是在一些更小的聚合体中。(C风格的结构体)。

这并非调用者的事:让数据成员私有化。只有在那些聚合了一堆值但不需要封装或提供操作的简单的C风格结构体类型的情况下,才可以把所有数据成员声明为公有的。避免把公有和非公有的数据混合在一起,这往往意味着一个混乱的设计。

42.  不要出卖你的内部数据。

不要自作多情:避免返回一个类所管理的内部数据的句柄,这样用户就不能不受控制地修改对象所拥有的状态。

43.  明智地使用Pimpl.

克服语言的分离欲望:C++可以让私有成员不可访问,但并不是不可见。考虑使用Pimpl惯用法让私有成员真正不可见,从而实现编译器防火墙和提高信息隐藏。(参见Item11Item41

44.  优先编写非成员非友元的函数。

避免友元的耗费:只要可能,就优先让函数既非成员又非友元。

45.  总是提供配对的newdelete

这是一揽子交易:每个重载了void* operator new(parms)的类都必须同时提供一个对应的重载void operator delete(void*, parms),这里的parms是一个额外的形参类型列表(第一个总是std::size_t)。数组形式的new[]delete[]也是一样。

46.  如果你提供了任何在类中声明的new,就要提供所有标准形式(plainin-placenothrow)。

不要隐藏标准形式的new:如果一个类定义了operator new的任何一种重载形式,就应该提供plainin-placenon-throwing所有三种形式的operator new的重载。你如果不提供的话,它们会被隐藏掉,而且对你的用户也是不可用的。

C++类继承下的赋值运算符

class Base { public: Base& operator=(const Base& rhy); Base(int val=0); private: int value; ...
  • gettogetto
  • gettogetto
  • 2016年01月20日 15:16
  • 1041

转:C++ Coding Standards

/*************************************************************************Scripts of C++ Coding Stan...
  • bat603
  • bat603
  • 2006年12月19日 16:42
  • 2591

C++中的重载运算符、继承、封装、多态讲解(进阶篇)

上次我们说到C++语言中的面向对象基本概念,那就是什么是类什么是对象,他们之间的关系是什么,本篇博文我们来说说,C++语言中重要的几个机制。(面试也经常会被问到这些知识点) 一个类可以派生自多...
  • songkai320
  • songkai320
  • 2016年07月15日 10:16
  • 1158

[C++]接口继承与实现继承

 接口继承与实现继承MoaKap所谓接口继承,就是派生类只继承函数的接口,也就是声明;而实现继承,就是派生类同时继承函数的接口和实现。我们都很清楚C++中有几个基本的概念,虚函数、纯虚函数、非虚函数。...
  • ljinddlj
  • ljinddlj
  • 2007年12月07日 11:45
  • 8803

C++ 运算符重载函数和实现

1、 三大件是:构造函数,析构函数,赋值运算符重载函数  2、在今天学习的代码中,我发现一些为题:    2.1 在构造函数中初始化类表的时候有时候容易把创建新空间的"[]"写成"()",虽然编译器不...
  • qq_28412897
  • qq_28412897
  • 2016年08月23日 08:58
  • 666

C++ 类的继承——继承的基础

继承意味着可以为一个类定义并编译一个非常泛化的形式。C++最强大的特性之一就是可通过继承,从一个类派生出另一个类。继承是根据一个类(称为基类)创建一个新类(称为派生类)的过程。派生类自动具有基类的所有...
  • sense_poetry
  • sense_poetry
  • 2016年05月25日 17:45
  • 469

C++-继承:基类与派生类的关系

成员函数的重定义和名字隐藏基类的数据成员和成员函数在派生类中都有一份拷贝,派生类能够直接访问从基类继承而来的public和protected成员,且只能够通过这两类成员访问从基类继承而来的privat...
  • ko_tin
  • ko_tin
  • 2017年02月23日 18:29
  • 332

C++继承类中析构函数的问题

解析函数要 virtual #include using namespace std; class CBase { public: CBase(int i){ m_data = i;cout ...
  • u012543266
  • u012543266
  • 2013年11月03日 20:43
  • 1960

c++ 类的继承与派生 知识点总结及例子

c++ 类的继承与派生 一、基本概念 1、类的继承,是新的类从已有类那里得到已有的特性。或从已有类产生新类的过程就是类的派生。原有的类称为基类或父类,产生的新类称为派生类或子类。 ...
  • wyl4138
  • wyl4138
  • 2016年05月19日 08:46
  • 483

【c++知识归纳】继承与多态(一)

c++是基于面向对象的编程语言,面向对象的三大特性为:封装、继承和多态。本文将我对继承与多态的理解进行了总结归纳,这部分内容对于学习c++编程语言是非常重要的,文章加入我的个人理解,希望能给大家带来帮...
  • XHfight
  • XHfight
  • 2016年08月24日 02:45
  • 1425
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ Coding Standards:函数与操作符;类设计与继承
举报原因:
原因补充:

(最多只允许输入30个字)