OpenOffice 代码约定规范

来源:互联网 发布:淘宝网一年的销售额 编辑:程序博客网 时间:2024/06/05 21:04

原文:https://wiki.openoffice.org/wiki/Writer/Code_Conventions
作者:OpenOffice.org

译文:http://www.aqcoder.com/blog/detail/id/6de0c3b2-8de4-11e5-bf2d-2a06cd74bd52/
译者:aqcoder

如何使用本代码约定

本约定为作为[ OppenOffice.org 代码规范(https://wiki.openoffice.org/wiki/Cpp_Coding_Standards)的附加说明为开发者制定 cpp 代码的编写约定。约定基本有实践总结得到。

命名约定

目前 OOo 代码命名规范是相当模糊的。“入乡随俗。”如果现有代码本身就是不一致将不对其做改动。本约定只做为新代码的命名约定。

工程结构、文件名、命名空间

  • 工程目录结构:源文件必须在模块的 source/ 目录下,包含头文件必须在模块的 source/inc/ 或者 inc/ 目录下。
  • inc/foo.hxx 或者 source/inc/foo.hxx 是给模块内部使用的头文件,而 inc/$PRJ_NAME/foo.hxx 是导出头文件。
  • 对于导出的头文件,尽量减小头文件的内部依赖,如果一个导出头文件一部分需要导出一部分内部使用,则切分这个头文件。
  • 文件名只能匹配为 [a-zA-Z][a-zA-Z0-9.-]*,且头文件/源文件的扩展名为 hxx/cxx。类名推荐使用驼峰法。
  • 命名空间全为小写。
namespace com { namespace sun { namespace star { }}}

有些老的模块使用前缀来代替命名空间,当在其加入新代码时使用包含在内的命名空间,不要新建模块。

namespace sw { namespace newnamespace {}}

类名、方法名

类名和接口

  • 使用大写前缀驼峰法命名类名
namespace sw{    class SomeClassExample;}

在 sw 模块,在全局命名空间的类需要加前缀 Sw

class SwSomeClassExample;
  • 接口以 I 为前缀,接口必须是纯虚基类。
namespace sw{    class ISomeInterfaceExample;}

方法

方法使用小写前缀驼峰法或者大写前缀驼峰法,通常以动词开头。

void SomeClassExample::appendChild();void fixUrlHeaders();

注意,甚至缩写通常大写都只有第一个字母大写。如果一个类没有遵循这个惯例,使用旧的惯例或更新类是完全符合本约定的。

  • 关于方法名使用大写前缀驼峰法还是小写驼峰法:当实现 UNO 接口时类的方法使用小写前缀驼峰法。
  • 本地方法使用静态函数,并且定义在匿名命名空间中,以 lcl_ 做为前缀。
  • 函数返回布尔值需要以回答问题的方式(译者注:应该是指一些成员函数)
bool hasChild();bool isLeaf();

变量、参数、成员、常亮

局部变量

  • 局部变量使用匈牙利命名法,用个小写字母做为前缀,紧跟着大写前缀名称。
const sal_Int32 aParameterName;const OUString& rParameterByReference;
前缀 含义 r 引用 x UNO引用 p 指针(包括 STL 风格的迭代器和智能指针,UNO 引用除外) a 一些值

有些值类型使用特定前缀而不是使用 a

前缀 含义 c 字符型 e 枚举类型 f 浮点型 n 整型 s 字符串型 v 容器 (vector)

如果一个方法没有遵循本约定,保持原来的约定或者更新到现有约定。
下面给出一些好的/坏的匈牙利符号

  • http://herbsutter.wordpress.com/2008/07/15/hungarian-notation-is-clearly-goodbad/
  • http://en.wikipedia.org/wiki/Hungarian_notation

  • 布尔类型变量需要使用回答的形式,使用 is/has 作为匈牙利前缀。

bool isLeaf;bool hasChild;

参数

参数命名遵从的规则和局部变量一致,但是有一些附加前缀:

前缀 含义 i_ 传入参数 o_ 传出参数 io_ 传入传出

如果函数没有遵从本约定,则保留原来的约定或者都改为遵从本约定。

成员变量

成员变量命名遵从局部变量的约定,但是需要加上前缀 ‘m_’。

SwPosition m_aPosition;Node const * const m_pParent;

如果函数没有遵从本约定,则保留原来的约定或者都改为遵从本约定。

静态成员变量

成员变量命名遵从局部变量的约定,但是需要加上前缀 ‘our_’。

static ::osl::Mutex our_aFileMutex;

如果函数没有遵从本约定,则保留原来的约定或者都改为遵从本约定。

常量

  • 不要使用预处理宏代替常量,尽量不要使用全局常量。
  • 如果可能的话尽量使用 static const 修饰常量。
  • 在 cxx 文件中,常量成员放到匿名命名空间中。(不要将他们放到头文件中)
namespace{    static const OUString sLogging = OUString::createFromAscii("com.sun.star.logging");}

typedefs 和模板参数

typedefs 必须以 _t 或者 _type 结尾。

class MyClass{    typedef ::rtl::OUString string_t;    typeded sal_Int32 element_t;};

模板参数必须以大写字母 t 开始,紧接着小写开头单词:

template<typename Tparam> class MyTemplateClass {};

一般命名规则和语义

命名前缀规则:

<scope-prefix>_<hungarian-prefix>VariableName;

scope-prefix 是如下其中一个:

前缀 含义 局部变量 i_ 传入参数 o_ 传出参数 io 传入传出参数 m_ 成员变量 our_ 金泰成员变量 g_ 全局变量 lcl_ 文件局部成员函数或变量

匈牙利前缀参考上文所述。

书写格式

Makefile 中的列表您可能的一个入口占一行,且按字母顺序排列,这样容易合并。

SLOFILES= \    $(SLO)$/config.obj \    $(SLO)$/corecontroller.obj \    $(SLO)$/errormail.obj \    $(SLO)$/invitejob.obj \    $(SLO)$/logpacker.obj \    $(SLO)$/logstorage.obj \    $(SLO)$/myconfigurationhelper.obj \    $(SLO)$/onlogrotatejob.obj \    $(SLO)$/oooimprovement_exports.obj \    $(SLO)$/soaprequest.obj \    $(SLO)$/soapsender.obj \
  • cpp 文件按如下顺序布局

    1. license
    2. includes
    3. defines (if and)
    4. global using statements
    5. anonymous namespace with local functions and data(implementation files only)
    6. anything else
  • 尽量保持每行少于 80 个字符(否则你就要考虑重构了)。在如下条件下可以忽略这条约定:

    1. 头文件声明不允许,类型名很长。
    2. 在子类声明中罗列基类的虚函数时不允许换行。
    3. 定义字符串常量。
    4. 断言字符串,等。

如果对可读性没有帮助,在这些情况下不要断行,记住:字符串常量可以断行:

static const SOME_STRING = ::rtl::OUString::createFromAscii(    "Libertatem quam peperere maiores digne studeat servare posteritas.\n"    "means\n"    "May the freedom won by our forefathers be conserved in dignity for posterity.\n");
  • 缩进方法遵循 Allman-Style

  • if 判断时,语义通顺且短,可以放在一行中:

if(!pData) return;

但是要注意即使语句很短,在调试的时候换行对设置断点是很有用的。所以尽量不要在 if 语句中使用一行。

  • 在一份声明中如果使用换行(如果 if 语句, 参数列表),不使用空间对齐语句。其不良维护。简单的缩进线继续发表声明就可以了:
Reference<XInterface> MyConfigurationHelper::openConfig(    const Reference<XMultiServiceFactory> xSMGR,    const OUString& sPackage,    sal_Int32 eMode){ }

当在一个列表(如参数列表或 for 语句)使用换行,使每条语句为一行。

  • 代码注释中不要包含时间戳(“created on”, “last modified by”),因为他们是无效的。在 bug/issues 中注明修改,即使只有简单的几行说明,这是为了方便问题回归。

通用约定

  • 在源文件中不要出现交叉包含。例如:sw/source/ui 下的源文件只能包含 sw 模块的全局包含目录 sw/inc 和 ui 下的包含目录 /sw/source/ui/inc。他不能包含项 /sw/source/core/inc 和 sw/source/filter/inc 这样的其他目录下的头文件。

  • 保证成员变量都是私有的或者是受保护的。如果需要的话生命内联属性器方法 getter/setter。属性器的名称是成员变量的名称去除前缀。如果一定要定义共有的成员请使用结构体关键字 struct 代替 class。

class SomeExampleClass{    public:        ::rtl::OUString getName();        void setName(const OUString& rName);     private:        ::rtl::OUString m_aName;};struct AnotherExampleClass{   public:       ::rtl::OUString m_aName;};
  • 函数实现不要超过 200 行(超过的话请重构)
  • 如果可能的话使用块限制局部变量的范围。一个局部变量应该很少超过一个屏幕的长度(30 - 60 LOC)。
  • 保证头文件的可读性
    ** 在头文件中使用 handle/body(pimpl) 或者虚基类来屏蔽具体的实现细节。使用 boost::scoped_ptr<>(详见 http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/scoped_ptr.htmhttp://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/sp_techniques.html) 代替纯指针,因为具体实现不需要暴露在头文件中。
    ** 尽量避免在头文件中定义私有的成员函数。如果实现函数只需访问一些成员对象,在匿名命名空间中实现这些函数。如果需要访问太多的成员对象,请重构。
namespace{    static sal_Int32 lcl_countLines(const Sequence<sal_Int8>& rBuffer)    {        ...    };}
  • 尽量避免暴露纯指针,使用 com::sun::star::uno::Reference 引用 UNO 对象,boost::shared_ptr<> 引用其他对象。如果需要纯指针就使用 shared_ptr<>.get()。无论何时都要保证访问的指针是有效的。很多时候使用 boost::weak_ptr<> 都是使用纯指针好。

  • 断言:在 OOo 中有很多种断言,通常都是一些宏定义:
    ** OSL_ENSURE 只有在 debug 下才有效。
    * DBG_ 是模块工具定义的。所以(therefore evil by definition?)

  • use mutable and explicit in new code

  • 在新代码里使用英文注释,不要在同一个方法中混合德语和英语,如果重构一个模块,把注释翻译成英语。

  • 不要使用 C-style 的类型转换,使用 C++-style 的类型转换。

  • 提供纯虚函数作为接口。

  • Do not link against specific implementations, link against interfaces.

  • 使用虚共有继承实现接口。

  • 在纯虚基类中使用宏 SAL_NO_VTABLE:

struct SAL_NO_VTABLE IMyInterface{   virtual void myMethod() = 0;};

Use SAL_DLLPRIVATE and SAL_DLLPUBLIC_* for large shared libraries that are not only exporting the few UNO component access functions. See e.g. svx/svxdllapi.h for a usage example.

  • 在非 UNO 组件的共享库中使用 SAL_DLLPRIVATE 和 SAL_DLLPUBLIC_* 指定导出,参考例子 svx/svxdllapi.h。

不宜使用的类型(已经被 OpenOffice.org 编码规范覆盖)

  • 不要使用 /svtools/svarray.h 或 /svtools/svstdarr.hxx 中的容器,或类似的代码。使用 STL 的容器。

  • 避免使用 tools/rtti.hxx 中的 rtti(运行时类型识别),使用 C++ 内置的 RTTI(type_info, dynamic_cast, typeid)。

  • 不要使用 “tools/contnr.hhx”, “tools/table.hxx”, “tools/stack.hxx”, “tools/queue.hxx”, “tools/dynary.hxx” 中的容器。使用 STL 代替。

  • 不要在新代码中使用 ByteString 或者 std::string,使用 OUString 代替。

  • 不要在新代码中使用 String,使用 OUString 代替。

  • 不要在新代码中使用 BOOL 或者 FASTBOOL,使用 bool 代替,在 UNO 中使用 sal_Bool。

  • 其他:如果 UNO 类型可用,使用 UNO 类型。

0 0
原创粉丝点击