先给官方链接一个 https://www.nsnam.org/develop/contributing-code/coding-style
1、缩进为2个空格,不用tab
2、命名方式
函数、方法和类型:驼峰式。
变量命名与驼峰式有下些许不同。例:变量 user name应该被写成userName,使用时:"UserName userName;"可以知道UUserName是类型名,userName是变量名。
全局变量应该以"g_"开头,成员变量应该以"m_"开头。
typedef的类型应该以大写 字母开头,由大写和小写字母组成,以"_t"结尾(可选)
定义的常量(如static const类成员或枚举常量)都是大写字母或数字,用下划线字符分隔单词。否则,不应在变量名中使用下划线字符。
例子
typedef int NewTypeOfInt_t;
const uint8_t PORT_NUMBER = 17;
class MyClass
{
void MyMethod (int aVar);
int m_aVar;
static int m_anotherVar;
};
最后,不要使用匈牙利表示法,不要给枚举、类和委托加任何字母的前缀。
3、名字选择:
变量、函数、方法和类型名应该基于美式英语。例:类型名:Packet, Buffer, Mac, or Phy;函数和方法名:GetX, DoDispose, ClearArray,。
长名字易于理解,短名字难以猜想(解释)。但是用tmp表示一个暂时变量、i表示一个循环的迭代,这些是可以的。
如果使用谓词(即函数、变量或方法会返回一个bool值)那么应该给这个名字加前缀 “is” or “has”。
4、文件排版和代码组织:
一个名为 MyClass 的类应该被定义在名为 my-class.h 的文件中,实现应该在名为 my-class.cc 中。目的是为了开发者快速定位。
每一个 my-class.h 的头文件应该以下面规范开头:
(1)第一行应该确保每一个用emacs编辑器的开发者能正确缩进代码
(2)以下几行确保你的代码是根据GPL授权的,版权所有者是正确标识的(通常是您或您的雇主),并且代码的实际作者被标识出来。
(3)最后部分纯粹是信息性,是为了修复bug和打补丁时找到最合适的人。请不要在版权声明后添加“保留所有权利”短语。
例:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) YEAR COPYRIGHTHOLDER
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: MyName <myemail@example.com>
*/
在上面这些C类型的注释下面,始终包含以下内容:定义一组用于避免多次包含该头的头保护(MY_CLASS_H),这确保代码包含在“ns3”命名空间中,并为类的API的公共部分提供一组doxygen注释。有关可用于Doxygen文档的标签集的详细信息,请参见Doxygen网站。例:
#ifndef MY_CLASS_H
#define MY_CLASS_H
namespace n3 {
/**
* \brief short one-line description of the purpose of your class
*
* A longer description of the purpose of your class after a blank
* empty line.
*/
class MyClass
{
public:
MyClass ();
/**
* \param firstParam a short description of the purpose of this parameter
* \returns a short description of what is returned from this function.
*
* A detailed description of the purpose of the method.
*/
int DoSomething (int firstParam);
private:
void MyPrivateMethod (void);
int m_myPrivateMemberVariable;
};
} // namespace ns3
#endif /* MY_CLASS_H */
my-class.cc文件应该像这种:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) YEAR COPYRIGHTHOLDER
*
* 3-paragraph GPL blurb
*
* Author: MyName <myemail@foo.com>
*/
#include "my-class.h"
namespace ns3 {
MyClass::MyClass ()
{}
...
} // namespace ns3
5、语言特色:
略
6、注释:
整个工程使用Doxygen归档接口,使用注释提高代码清晰度。所有公共可以用的方法(public methods)都应该有Doxygen注释。Doxygen注释应该使用C注释的风格。对于非公共的方法(non-public methods),应该用@internal 进行标记。请使用@see 标记交叉引用。所有参数和返回值也应该被记录。
对于代码中的注释,在单独阅读代码后不能明显了解意图或算法的地方,应该使用注释来描述意图或概括算法。
没有最低的注释要求,小的程序可能根本不需要注释,但希望许多较大的程序会有注释,以帮助未来的维护人员。请全部都写成英文,每句的开头字母都用大写,每个句子后加两个空格。短注释可以使用 “//” ,但是长注释应该使用“/*” “*/”。例
/*
* A longer comment,
* with multiple lines.
*/
变量声明因该有一个短,一两行的注释描述该变量的意图,除非这是个很容易区分局部变量。
简短注释应与变量声明位于同一行,除非它太长,在这种情况下,它应位于前一行。
每个函数前面都应该有一个详细的(doxygen)注释块,描述函数的功能、形式参数以及返回值(如果有的话)。
允许使用doxygen样式 “\” 或 “@” 。每个类声明前面都应该有一个(doxygen)注释块,用于描述类的用途。
7、强制转换
Where casts are necessary, use the Google C++ guidance: “Use C++-style casts like static_cast(double_value), or brace initialization for conversion of arithmetic types like int64 y = int64{1} << 42."
Try to avoid (and remove current instances of) casting of uint8_t type to larger integers in our logging output by overriding these types within the logging system itself. Also, the unary ‘+’ operator can be used to print the numeric value of any variable, such as:
uint8_t flags = 5;
std::cout << "Flags numeric value: " << +flags << std::endl;
Avoid unnecessary casts if minor changes to variable declarations can solve the issue.
(水平有限,这部分就不翻了)
8、杂项
下面这一行应始终是每个文件的第一行
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
NS_LOG_COMPONENT_DEFINE("log-component-name");
语句应放在命名空间ns3(用于模块代码)内,并放在 using namespace ns3 后面。
const 常量语法:
void MySub (const T&); // Method 1 (prefer this syntax):推荐
void MySub (T const&); // Method 2 (avoid this syntax):避免
在函数名和括号间加空格,函数声明和调用时也一样。
void MySub(const T&); // avoid this
void MySub (const T&); // use this instead
不要在任何头文件中用内联函数,把所有实现放在 .cc 中,除非在头文件中的实现带来了可论证和显著的性能改进。
不要使用“nil” 或者“NULL”;应使用“0”(提高可移植性)
考虑你是否需要类中的默认复制构造函数和赋值运算符,如果不需要,请将它们设置为私有的,如下所示:
private:
ClassName (const Classname&);
ClassName& operator= (const ClassName&)
避免返回引用给一个对象的内部或局部成员。
a_type& foo (void); // should be avoided, return a pointer or an object.
const a_type& foo (void); // same as above
通过访问函数暴露类的成员,而不要直接访问公共对象。这种访问函数通常叫 “Get” 或 “Set” 什么的。
对于标准头文件,使用C++风格的include,如
#include <cheader> //prefer
#include <header.h> //avoid
不要使用 “using” 指令将C++标准库命名空间引入ns-3源文件,即避免使用“using namespace std;"
在其他ns-3文件中包含ns-3头文件时,如果希望在 build/ 中找到头文件,请使用<>,如果知道头与实现在同一目录中,请使用 “” 。在 .h 文件中,要始终用
#include <ns3/header.h>
在 .cc 文件中,要用
#include "header.h"
当写library的时候,……(略)