一、类名命名规范及使用约定类名命名规范根据各种类的类型和用途,采用不同前缀+名词的命名方式。名词采用波浪法,必须使用可以明确表达变量意义的英文名词。前缀UE封装类模板类以T为前缀。继承UObject的类以U为前缀。继承AAtor的类以A为前缀。继承SWidget的类以S为前缀。抽象接口类以I为前缀。枚举类由E为前缀布尔变量必须以b为前缀(比如“bPendingDestruction”,或“bHasFadedIn”)大部分其他类都以F为前缀,但某些子系统使用其他字母。Typedef应该由相应的类型来前缀:F则说明是struct的typedef,U则是UObject的typedef,以此类推o对于一个模板的特定化实例来做的typedef则不再是模板,应该用相应的前缀来定义。比如:typedefTArrayFMyTypeFArrayOfMyTypes;普通类(C++)一般类,采用C+名词的方式命名例如:ClassCPerson{Protected:Stringm_strName;Stringm_strNickName;};接口类(I)对于无任何实现的纯虚类,称为接口类,这些类的特点都是无任何成员变量,存在需要其他实现类实现的纯虚函数。接口类必须采用I+名词的方式命名。例如:classIDataInput{Public:virtual~IDataInput(){};virtualvoidread()=0;}结构体(T)Struct,结构体,必须以T+名词的方式命名。例如:typedefstruct_t_mystruct{Unsignedintnumber;Unsignedintvalue;Charname[255];}TMyStruct,*TMyStructPtr;模板类模板类,必须以全小写命名。例如:templateclassT,allocatorAclassscreen:publicmapT,A{}类成员的初始化(Memberinitializationlists)成员的初始化必须在构造函数名的下一行开始正确写法:gribble::gribble():m_private_data(0),m_more_stuff(0),m_helper(0){}错误写法:gribble::gribble():m_private_data(0),m_more_stuff(0),m_helper(0){}二、数据变量命名规范常量的命名规范:常量名由全大写字母组成,单词间通过下划线来界定。如:constInt32MAX_AMMO=100;成员变量的命名规范:m+_+[变量类型]+变量名m后带上明确表达变量意义的英文名词而不要用难以表达意义的缩写。且m后的变量名首字母必须大写。如:classCMyGame{private:CPointm_Point;―――普通类型CGame*m_pGame;―――指针类型Int32m_nGameID;―――整数类型}函数参数的命名规范:采用波浪法来定义函数参数变量。同样的,也必须使用可以明确表达变量意义的英文名词,而不仅仅是缩写。[变量类型]+变量名如定义一个读取文件的函数,并且用参数传入一个文件名publicbooleanreadFile(StringstrFileName){…m_sFileName=strFileName;}局部变量的命名规范:采用全部小写的方式定义局部变量名。而且尽量用有意义的名词作为变量名。局部变量不需要在前面增加变量类型标识。publicbooleanreadFile(){Stringfilename=“e.ext”;}局部循环变量的命名规范:用小写的i、j、k依次作为循环变量如:for(inti=0;i10;i++){for(intj=0;j10;j++){}}使用Auto如:TMapFString,int32m_mapTest;for(auto&Kvp:m_mapTest){UE_LOG(LogCategory,Log,TEXT(Key:%s,Value:%d),Kvp.Key,*Kvp.Value);}临时变量的命名规范:一般情况下尽量使用有意义的变量名,如果是某变量的临时变量,可采用前面增加tmp前缀的方式。如果实在没办法,可采用tmp、temp等作为临时变量名,但不可以过多定义诸如tmp1、tmp2等变量,如果出现此情况,则必定可以采用有意义的名词代替。inttmpserialno=m_nSerialNo++;tmpserialno%=10;m_nSerialNo=tmpserialno;枚举常量采用波浪法加E前缀来定义枚举常量。同样的,也必须使用可以明确表达变量意义的英文名词,而不仅仅是缩写。且E后首字母必须大写例如:UENUM()enumclassEThing:uint8{Thing1,Thing2};基本C++数据类型的可移植别名bool代表布尔值(永远不要假设布尔值的大小)。BOOL将不会进行编译。TCHAR代表字符型(永远不要假设TCHAR的大小)。uint8代表无符号字节(占1个字节)。int8代表有符号的字节(占1个字节)。uint16代表无符号短整型(占2个字节)。int16代表有符号短整型(占2个字节)。uint32代表无符号整型(占4字节)。int32代表带符号整型(占4字节)。uint64代表无符号四字(8个字节)。int64代表有符号四字(8个字节)。float代表单精度浮点型(占4个字节)。double代表双精度浮点型(占8个字节)。PTRINT代表可以存放一个指针的整型(永远不要假设PTRINT的大小)。请不要在可移植代码中使用C++整型,因为需要根据编译器决定这种数据类型的大小。变量类型:基本类型(保留类型)类型前缀示例TCHARccMyChar;boolbbMyBool;int/short/long/uint8/uint16/int16/uint32/int32uint64/int64nnMyInt;float/doubleffMyFloat;FStringstrstrMyStringFNamenanaMyNameFTextttMyTextTArrayarrarrMyPlayersTMapmapmapPlayersFVector/FVector2DvecvecPlayers指针类型:在变量类前增加p标识,作为标识此变量为指针类型,如:int*pKey=NULL;CDateTime*pDateTime=newCDateTime(0);数组变量命名规范:对于数组类型的变量,需要采用复数s以标识此为数组变量。如:intm_nKeys[100];doubledValues[200];CMyClassStrings[200];对于数组指针变量,同样在类型前增加p标识。在删除的时候,必须用delete[]的方式删除动态数组,以保证数组内的实例被调用析构函数。CDateTime*pBirthdays=newCDateTime[20];....delete[]pBirthdays;int*m_pnKeys=newint[20];三、函数命名规范函数名称原则上采用动词名词的组合形式,函数名称采用波浪法,私有函数(private)第一个单词首字母采用小写,后面的单词的首字母采用大写,受保护函数和公开函数(protected和public)第一个单词首字母采用大写如:private:intgetTopicID();protected:voidOnClick();public:ACharacter*GetPlayer();成员变量必须采用private的定义,不允许使用public定义,并置于类定义的最后,另外用getter和setter的函数访问和修改之(在需要考虑程序大小或者需要将成员变量暴露给蓝图的时候可以忽略此规则)classCTest{public:intgetTopicID(){returnm_nTopicID;}voidgetTopicID(intnTopicID){m_nTopicID=nTopicID;}UPROPERTY(EditAnywhere,BlueprintReadOnly,Category=玩家属性)FNamem_naPlayerName;private:TIntm_nTopicID;}一个函数只完成一个任务,不要把多个任务放在一个函数中,即使那些任务非常小服务端消息或客户端消息都应该以handle开头handleLoginhandleLogouthandleMainViewClosehandleGoldChange事件的响应函数和派发函数都应该以On开头OnDeathOnPickupOnReceiveMessageOnMessageRecievedOnTargetChangedOnClickOnLeave每个函数的大小不要超过100行四、Const正确性const既是对编译器工作的引导,也是说明文档,因此应该尽可能的遵守正确使用const的形式。这里包括当函数不修改传入参数时,应在参数中使用const指针或引用,如果一个函数不修改对象则将它标记为const,以及在对于不修改外部容器的循环使用const修饰。voidSomeMutatingOperation(FThing&OutResult,constTArrayint32&InArray);//InArray不可以被函数内部修改,但OutResult的属性可以被修改voidFThing::SomeNonMutatingOperation()const{//此代码不会修改它所在的类(this)的成员变量}TArrayFStringStringArray;for(constFString&:StringArray){//该循环不可以修改StringArray的内容}Const也应该对于使用值的方法下被使用。这里就告诉代码的读者该变量并不会在函数体内修改,会帮助理解代码。这么做的事情也请保证函数申明和定义一致,因为这也会影响JavaDoc的过程:voidAddSomeThings(constint32Count);voidAddSomeThings(constint32Count){constint32CountPlusOne=Count+1;//函数内部不可以对Count或者CountPlusOne进行修改}这里有个值传递参数的例外(查看Movesemantics),但这种情况很少见。voidFBlah::SetMemberArray(TArrayFStringInNewArray){MemberArray=MoveTemp(InNewArray);}将const关键字放到后面来表示一个指针本身是常量(而不是它指向的内容)。这里表示该指针无法被“重新指向”。//指向T类型的常量指针,它不能再指向别的变量,但指向(变量)的值可以修改T*constPtr=...;不要用const来修饰返回值类型,这是一个movesemantics的用法,为了复杂类型并会对内建类型产生编译警告。这条规则仅对数组类型本身起效,并不对返回的指针类型或引用类型的目标起效。//不建议-返回一个常量数组constTArrayFStringGetSomeArray();//推荐-返回一个常量数组的引用constTArrayFString&GetSomeArray();//推荐-返回一个常量数组的指针constTArrayFString*GetSomeArray();//不建议-返回一个常量数组的常量指针constTArrayFString*constGetSomeArray();五、其他良好的编程习惯缩进采用tab而不是用space;tab的缩进显示距离建议为4个空格用一个空行来分开代码和逻辑的分组;大括号{}if-else语句的每个代码执行块都应该位于大括号内。这是为了防止编辑错误-如果没有使用大括号,某人可能会不经