VC的编码规范,现在应该有很多版本了。我想,规范只是一种普遍的要求。比如法律,道德观。虽多但不一定全。大家在编程中肯定会有一些自己的风格。希望大家在本贴中发表一下自己在编程中喜欢的风格。
另外,在面向对象这个前提下,我们应该如何来开发VC项目。包括可行的经验,和不可行的经验。希望大家踊跃发言。
相信我们的成功或者失败的经验都能给后来者以启发。

解决方案 »

  1.   

    纯属个人习惯:
    我喜欢所有单纯的set和get都inline,喜欢每个类生成时都去掉VC自动生成的virtual destructor,除非自己认为一定有virtual的必要。喜欢使用STL的container而不是MFC的container。
      

  2.   

    还有一个为大师所不耻的:
    使用STL container时喜欢使用指针。其实就我现在开发的这几个不算太大的项目,只要自己的逻辑完备,这么用也未尝不可,且效率高。
      

  3.   

    喜欢思考问题Top-down,实际编码Bottom-up。子系统间Composite,子系统内部能Composite就不Inherit,能不多态就不多态。总是使用working thread来完成非界面的逻辑,只在main thread里写界面相关的调用。
    请大家多批评。
      

  4.   

    说个题外话:喜欢听Java程序员夸夸其谈,偶尔和他深入探讨一下底层机制时欣赏他无奈的表情。
      

  5.   

    不喜欢套用设计样式,但不管什么项目到头来都会落入某些经典的设计样式里(无奈,前人的成果确实伟大)。能不用MFC的地方就不用,但MFC的MVC我还是很喜欢的。
      

  6.   

    出现问题第一反应是查MSDN,同时在MSN上问同学,这两条路不行时,上csdn问问题,然后马上去vckbase和codeproject找。基本上所有问题都在csdn有人回答前解决了。
      

  7.   

    出现问题第一反应是查google,同时查MSDN,同时上codeguru找。基本上所有问题都能解决,不能解决的到csdn也解决不了,总体来说csdn解决不了我的任何问题。
      

  8.   

    不过常上csdn东翻翻西翻翻,有些东西可以拓宽知识面,做技术储备
      

  9.   

    我的编程风格:
    1、使用自定义的宏,完成一定的注释或其他的功能!
    2、定义变量:
       一般在函数的开头定义,定义后注明变量的用意。
    3、函数的定义:
       类型函数名各占取一行,类似:
       VOID MyFunction(int iCount)
    定义时使用:
       VOID
       MyFunction(
       int iCount)
    {
     ......
    }
    4、局部变量不加前缀,比如:
       BOOL bHide = FALSE;
    5、全局的一般加入一个前缀g_,比如:
       BOOL g_bMaterail = FALSE;
    6、一般命名原则遵循匈牙利命名原则。
    函数的说明格式如下:
    ///////////////////////////////////////////////////
    // ------------------------------------------------
    // 函数名称 :
    //
    //
    // 函数功能 :
    //
    //
    // 函数参数 :
    //
    //
    //
    //
    // 函数返回值 :
    //
    //
    // 函数编写修改人 :
    // 函数修改日期 :2004-3-22 15:00:50
    // ------------------------------------------------
    /////////////////////////////////////////////////// 
      

  10.   

    匈牙利命名,与系统保持一致不用自己不熟悉的东西,如果必须用,先熟悉他知其然所以然出现问题,先尝试自己解决提交模块时,提供调用demo不盲目面象对象变量一般用到时再定义
      

  11.   

    我在最后的公司的代码规范(原创):
    1.变量命名:
    以匈牙利命名法为基础,如:
    int g_iMaxNumber; //全局变量
    float fInput;     //局部变量
    CWnd* m_pOutputWindow; //成员变量前缀如下:
    (以下为Charles Petzold 在 programming windows 中使用的标准)
    (括号内为该类型的原型)
    c char or WCHAR or TCHAR 
    by BYTE (unsigned char) 
    n short 
    i int 
    x, y int used as x-coordinate or y-coordinate 
    cx, cy int used as x or y length; c stands for "count" 
    b BOOL (int);
    w WORD (unsigned short) 
    l LONG (long) 
    dw DWORD (unsigned long) 
    fn     function 
    s string 
    sz string terminated by 0 character 
    h handle 
    p pointer补充:
    f       float
    d       double(以下为MFC常用的部分标准)
    str CString
    pt  CPoint
    t   CTime窗口类指针(CWnd)可当作普通指针申明,加前缀p即可,但应在名称中出现
    window(或wnd)字样,如下:
    CWnd* m_pOutputWindow;
    CWnd* m_pFirstInputWnd;命名类的成员变量时加前缀m_
    命名全局变量时加g_对一般类的变量进行命名时,若类名称较短,可当作类型处理,小写打头,如下:
    CButton buttonHolter
    当名称较繁时,可采用如下形式:
    MynameClassname
    其中,Myname表示当前变量代表的逻辑意义,Classname代表类名(可缩写,简写)
    譬如:
    CButton HolterButton命名时使用拼音或英语单词(缩写)均可
    函数命名使用英语单词组合时一般采用“动词 + 名词”的格式,如:
    BOOL OpenWindow(int iIndex); //打开iIndex指定窗口
    void ChangeWaveShape(); //改变波形  
    而不采用如下方法:
    BOOL WindowOpen(int iIndex);
    void WaveShapeChange();对于获取类的成员变量或设置类的成员变量的函数,一律命名如下:
    Get*();
    Set*();对于表示信息判断的函数(BOOL型),一律如下命名:
    Is*();全局变量命名尽可能使用完整的单词,尽可能长一些。
    局部变量应尽可能简短,可多使用常用缩写词。变量一般在使用处声明。
    注意不要在switch内声明变量。2.代码格式
    尽可能空行,将执行最小功能组或最小意群的代码放在一起,如下:
    //……//初始化
    Initial();//读取数据
    PrepareRead();
    Read();
    EndRead();//数据处理
    CheckData();
    DowithData();//数据输出
    PrepareWrite();
    Write();
    EndWrite();//……
    括号内的每一项应在逗号后空格,"("后不空格,如:(int iFirstInput, int iSecondInput)
    代码缩进应与Visual Studio默认的缩进格式一致(可使用Alt+F8自动校正排版)。每一个if,else,for,while一般应使用大括号
    对于if,else有一种情况可除外,即只有一句简单执行语句时,如下:
    if(……)
        bFlag = TRUE;
    else
        bFlag = FALSE;一般算术表达式变量之间均应空格,如:
    result = a * b / (c + d) + f
    仅当两变量之间关系较其它变量在逻辑上明显密切时,可不加空格。
    赋值语句格式:int i = 0;
    if语句格式:  if(bFlag == TRUE);
    for语句格式: for(int i = 0; i < MAX; i++)
    switch……case语句(若case的内容较复杂,则应加大括号):
    switch(iNum)
    {
    case 1:
    FirstFunc();
    break; case 2:
    SecondFunc();
    break; default:
    DefaultFunc();
    }每行代码不应超过屏幕,即应在不拖动水平滚动条的情况下可浏览整行,
    代码太长需分行时,应在本行最后一个逗号后加1空格,再加“\",
    分行后,一般应与上一行的括号内的内容左端对齐(可灵活处理),格式如下:
    StretchBlt(hdc, xPos + xQiPanLeftTop, yPos + yQiPanLeftTop, Width, Height,    hdcMem, 0, 0, Qizi_Width, Qizi_Height,SRCCOPY);3.注释
    每个文件最前端应有文件版本号标志及简单说明,如下:
    /**************************************************/
    /* 文件名:CTree.cpp              */
    /*     */
    /*  CTree的实现文件,CTree为tree的基类     */
    /*  当前版本:1.0.1.9     */
    /*     */
    /* 创建人:XXX                              */
    /*  创建时间: 2001.5.14     */
    /*  最后修改者:XXXX          */
    /* 最后修改时间: 2001.5.20     */
    /**************************************************/版本标志说明:1.2.3.4
    第一位1.为大版本号    通常软件有重大功能改进时增加此值
    第二位2.为小版本号   通常软件发补丁版时增加此值,大版本号更新时,此值归零。
    第三位3.功能版本号   软件修补小BUG时的内部调试版本增加此值,小版本号更新时,此值 归零
    第四位4.编译版本号     软件每完成一个能成功编译的版本时,此值加1,注:此值不归零。注释多使用//
    当要注掉一行以上的连续代码时,一律使用/* */,且退格标在行首,单独成行,格式如下:
    /*
    if(parentnode->LeftChild == NULL)
    {
    parentnode->LeftChild = childnode;
    childnode->ParentNode = parentnode;
    }
    */注释应该尽可能多,尽可能详细、准确。
    一般应保证在任意一屏有多于三行的注释。
    注释一律采用中文。
    连续的注释应尽可能对齐,保持美观,如:
    void Initial(HWND hWnd); //程序必要的变量初始化
    void DrawQipan(HDC hdc); //画棋盘
    void DrawAllQizi(HDC hdc); //显示棋子
    void DrawChildQizi(HDC hdc); //显示虚棋子
    UINT GetQipanPos(POINT ptMouse); //传入逻辑坐标,得到该坐标在棋盘上的位置函数实现处应至少有函数功能、入参、出参、返回值的注释。除循环计数以外,所有的变量(包括局部变量,临时变量)在声明时均应有注释。
    循环计数指定使用:i,j,k,m,n每一个实现算法的代码均应有算法的简短注释,或标明算法说明文档的位置对于起重要作用的变量,在程序中多处说明4.其它
    每个函数的内容一般不超过100行,太长时应分拆,集中的算法处理除外。凡可能涉及到优先级时,均应加括号每个头文件均应添加如下类似代码:
    #ifndef _INCLUDE_H
    #define _INCLUDE_H
    ……
    #endif所有的宏定义放在define_.h头文件中所有非成员变量应在声明时赋初值
    指针初值应赋空值,如:int* pCountNum = NULL;
    成员变量在构造函数内初始化(包括使用构造初始化列表)仅在代码简短而且逻辑简单清晰的情况下可使用?:操作符
    不使用","操作符必要安全性检查:a.所有指针在使用前应进行是否为空的判断b.所有BOOL型的函数应对返回值进行判断c.所有入参和出参应在函数入口对其进行合法性进行验证(空否,范围)d.所有I/O操作,应使用try(),catch()捕捉错误。e.每一次COM(组件对像模型)接口的调用,应检查返回值f.在申请大空间时,譬如new int(1024 * 1024)时,应使用try(),catch()捕捉错误。g.对于DC资源,譬如HDC、HPen、HBrush……等,使用后一定要释放。
      

  12.   

    顶!谢谢楼主   
    现在正在学习vc 能不能问个问题 。net到底是什么呀?我看到一些vc。net   vb。net等等不知道到底什么叫。net
      

  13.   

    关键是程序能正确运行,多测试。我的程序测试人少,如果大家有时间,帮忙测试一下。
    http://www.freewebs.com/3jj
      

  14.   

    如果我是自己写程序,肯定有比较详细的注释,包括:
    1. 函数参数和返回值及其功能的注释
    2. 重要变量的注释,特别是全局变量
    3. 程序段注释,即某段程序是干什么的
    4. 程序流程的简单说明
    5. 数据流程的简单说明
    6. 特殊的代码处,需以详细注释不过修改别人的程序则不一样,现在修改的,什么都没有,没有缩进,没有注释,没有任何说明,数据库结构也得打开SQL的表去看其结构,表间关系只有靠读程序和数据库里边的内容来判断,所以,算了吧,我也懒得写注释,程序流程了,随之走缩进就严格按照默认的
    命名,以匈牙利法为基础,大体上遵循而已变量的声明:
    1. 程序全局的,另开一个头文件和实现文件
    2. 类全局的,另开一个private或者是public项来声明
    3. 函数内的,先一齐声明所有变量,然后再使用注释的上一行如果是代码,则需要加一行空格,如果是第3种注释,则要加至少两个空行.如果是{ 则不空行
    函数间必有空行,尽量按照功能连续来放置函数
    如果是全局函数,则要另开新的头文件和实现文件,而且一类全局函数是一对头文件(如果函数很少,也可以用同一个头文件)
    如果有define的,则要另开一个新的头文件
      

  15.   

    谢谢谢谢,
    谢谢happyparrot提出了这个问题,
    谢谢“天外流星”给出了如此详细的规范,:)
    一直以来都在想着如何使自己的代码写得规范,
    却又苦于无人指导,我想我在这可以有进展了,:)
      

  16.   

    好贴!
    这是我们公司的:
    一、设计
    1、设计应该考虑到可移植性、可扩展性。
    2、注意界面和实现的分离。
    二、编码
    1、C++语言优先权。除接口、界面等与Windows相关的程序外,能用标准C++解决的问题尽量用标准C++解决,而不要使用Windows库及第三方库。
    2、代码力求清晰、简明,风格大体一致。
    3、不要使用无意义的名字做变量名、函数名、类名等。
    4、为了便于交流和维护,函数声明前应该有函数功能、参数和返回值注释说明,类、结构体和枚举及成员应该有必要的说明。在程序中加入必要的注释。
    三、编码风格参考:
    .h文件
    /*
     (版权说明、文件说明、作者、修订说明) 
    */#include <iostream>
    #include <string> // 我的工作
    enum ZMyWork
    {
    ZMY_WORK_TEACHER = 1, // 教师
    ZMY_WORK_WORKER = 2 // 工人
    };// 我的信息
    struct ZMyInfo
    {
    std::string Name; // 名字
    int Age; // 年龄
    };// 我自己类
    // 描述〈可选〉
    class ZMySelf
    {
    public:
    // 构造函数
    ZMySelf(void); // 获取我的名字
    // 返回我的名字
    std::string GetName(void) // 重新设置我的信息
    // Name ---- 新的名字
    // Age ---- 新的年龄
    // 成功返回true,失败返回false
    bool Reset(const std::string& Name, int Age);
    private:
    std::string m_Name; // 我的名字
    int m_Age; // 我的年龄
    };
      

  17.   

    //------------------------some func begin-----------------------------
    ...
    //------------------------some func end-------------------------------
    我一般是这样的,多了就不写了
      

  18.   

    我的写程序方法就是<<我是一只鱼>>自由的游来游去.没有规则就是我的规则.
      

  19.   

    谢谢楼主提出这个问题!
    我刚刚开始用VC编程!有许多问题不清楚!
    但看了看林锐的《C/C++高质量编程》,觉得里面的规范确实值得学习!
    但如果具体每个人都那样操作,可能会很难,所以觉得也只有大家慢慢提高自己的编程素质,才能有更好的团队开发,有更优秀的作品!努力 + ing !!!
      

  20.   

    用visual assist,规范和代码输入都省力很多
      

  21.   

    编码心得:
    设计阶段:
    1 先弄清楚软件所实现得流程;
    2 找出核心模块;
    编码阶段:
    1 编码时,变量,函数名用统一得规则命名,用英文命名,不用拼音;
    2 编码时,采用缩进规则;
    3 如果有相似得功能,尽量做成公共函数;
    4 公共变量尽量放在文件得开头,局部变量尽量放在函数得开头,便于查找;
    5 如果有拿不准得情况,在代码中一定要注释,否则,时间一长,连自己也弄不清了。而且,要尽快弄清楚。
    6 一个函数得功能,局部变量,参数,一定要标注清楚;
    7 每个模块,C文件,CPP文件,H文件的开头,一定要注释清这个文件实现的主要功能,或者功能库,尽量用E文
    8 C和CPP文件也按功能划分,然后,公用的部分,放在一个或几个文件里;
    9 实现功能时候,尽量使用标准的C库和C++库。
    我现在只想到了以上的少量经验。如有遗漏,后面再补充。
      

  22.   

    1. 编码时<头文件中> 功能相似,或者完成某一个大的功能的函数放在一块
    2. 函数的返回值必须要有意义,并且注意可扩充性
    3. 头文件中 变量/函数的定义与编译器自己产生的区分开来
    4. 尽量多一些注释,包括本模块的功能,函数的功能,变量的要求,返回值的意义等.
    5. 尽力多采用C++的风格 比如少用宏定义之类的.
    6. 多注意函数/代码的安全性,比如指针是否为空,下标是否越界等,在开发调试的时候可以用ASSERT进行提示
    7. 分析问题的过程
    7.1 功能目标是什么 大致的目标确定 然后对这些目标细化
    7.2 关键的功能是什么
    7.3 有何具体要求,难度,难点何在
    7.4 需要注意的问题
    7.5 进行按功能模块分类..暂时想到这么多...感谢楼主呀...
      

  23.   

    函数名与左括号之间应该加不加空格?
    WinMain(int,还是WinMain (int,?
      

  24.   

    回复人: BLsoft(网龙) ( ) 信誉:75  2004-07-15 12:21:00  得分: 0  
     
     
       我的写程序方法就是<<我是一只鱼>>自由的游来游去.没有规则就是我的规则.
     
     
    这样做的确可以把信誉分成功减到75分:)
      

  25.   

    我用的是MFC的风格,它里面怎么定的,我就照着定如果写的代码里没有用MFC 我就会用C++ Primer 里的习惯用法
      

  26.   

    俺就喜欢for,从不用while!
    呵呵!
      

  27.   

    钻研微软MFC代码, 追求清新.
      

  28.   

    To: taianmonkey() 
    类型函数名各占取一行,类似:
       VOID MyFunction(int iCount)
    定义时使用:
       VOID
       MyFunction(
       int iCount)
    {
     ......
    }
    这样写的好处是什么?谢谢!
      

  29.   

    我觉得if语句这样写可读性要好:
    if ( var1 == XXX )
    {
    ...
    }
      

  30.   

    命名基本采用匈牙利,全局 g_ static s_ ,const c_ privat m_
    比如: gsc_xxx 表示是一个全局静态常量;编码采用成对原则:
    比如 有new 就写 delete
    一写for,就输入 for (; ; )
                    {
                    }
    一打{就补换行和}设计采用极限编程思想,先实现核心框架再扩展!格式基本上采用公司规范!和华为公司的要求差不多!大家可以更深入的探讨各种设计思路,比如一般错误处理采用什么机制,如何安排调试时间等等!
      

  31.   

    范型的用 STL 风格
    MFC 用匈牙利
    其他用 .NET 风格
      

  32.   

    请教:如何排版长的语句:
    CString m_strConnect;
    m_strConnect.Format("Provider=OraOLEDB.Oracle; Data Source=%s; User ID=%s; PassWord=%s",strDataSource, strUserID,strPassWord);
    我的方法:
    1:
    CString m_strConnect;
    m_strConnect.Format(
    "Provider=OraOLEDB.Oracle; Data Source=%s; User ID=%s; PassWord=%s",
    strDataSource,
    strUserID,
    strPassWord);
    2:
    m_strConnect.Format("Provider=OraOLEDB.Oracle; Data Source=%s; User ID=%s; PassWord=%s",
    strDataSource,
    strUserID,
    strPassWord);
    3:
    m_strConnect.Format("Provider=OraOLEDB.Oracle; Data Source=%s; User ID=%s; PassWord=%s",
    strDataSource, strUserID, strPassWord);
    4:
    m_strConnect.Format(
    "Provider=OraOLEDB.Oracle; Data Source=%s; User ID=%s; PassWord=%s",
    strDataSource, strUserID, strPassWord);
      

  33.   

    我比较喜欢第四种方式我认为if语句还是这么写比较好if ( TRUE == bIsTrue)
      

  34.   

    编码风格的一致是最重要的,反而用什么风格并不重要。
    在一个project中,坚持一种统一的注释方式,函数调用习惯,
    (比如,在一个函数中,是用
    bool someFunction(Type& result);   // return是否成功,result为结果。
    还是
    Type someFunction(void);           // 直接返回结果,如果为某个确定特殊值则失败。
    )
    还有资源的管理方式,异常的使用,先把这些基础结构定义好,
    在编程的过程中,最重要的是保持程序逻辑结构的清晰简单。但要在一个project自始至终的坚持一种统一的风格比较困难,会有各种客观的原因
    促使你放弃它,并为自己找到很好的借口--工期太紧,特殊的客户需求等等。
    总之,实际的开发实际上太可能做到理想状态,比较理想都不能。就算是---你也一直
    认为自己是---一个优秀的程序员。
      

  35.   

    TO  eeixy2000(eeixy2000):
    长的可以这样排版Status = lpAcceptEx(
        g_sListen[nIndex],
        lpAcceptIoContext->sClient,
        lpAcceptIoContext->wsaBuffer.buf,
        0,
        sizeof(SOCKADDR_IN) + 16,
        sizeof(SOCKADDR_IN) + 16,
        &dwBytes,
        &lpAcceptIoContext->ol
       );
      

  36.   

    我的风格基本上是WINDOWS DDK里的 代码风格、。文件头:/*++Copyright (c) 2004 - 
          
     http://www.xxxx.comModule name  VNetSvr.h
     
    Abstract:
    Author:
     
      PPP    [email protected] 
      
    Environment:     Windows2003  Server 
     
    Notes:
    Revision History: created: 26:06:2004   11:05

    --*/函数:
    DWORD IOCOMP_Connect(char *pszRemoteIPAddr, unsigned short uRemotePort)
    /*++Function Description:       创建一个套接字,设置相应的属性,连接到在参数里指定的远程地址,
       并与完成端口相关联,然后返回此连接的IDArguments:    pszRemoteIPAddr - 要连接的远程IP地址
       uRemotePort - 要连接的远程端口Return Value:    连接成功返回连接的ID;失败返回0。--*/
    {
    struct sockaddr_in InterNetAddr;
    SOCKET             s;
    int                nResult        = 0;
    LPCOMMON_OBJECT    lpCommonObject = NULL;
    HANDLE             hrc            = NULL;
    ZeroMemory(&InterNetAddr, sizeof(InterNetAddr));
    InterNetAddr.sin_family      = AF_INET;
    InterNetAddr.sin_port        = htons(uRemotePort);
    InterNetAddr.sin_addr.s_addr = inet_addr(pszRemoteIPAddr);

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET)
    {
    return 0;
    }


    //
    // 设置套接字属性
    // if (!IOCOMP_SetSocketOpt(s))
    {
    closesocket(s);
    return 0;
    }

    nResult = connect(s, (PSOCKADDR)&InterNetAddr, sizeof(InterNetAddr)); 
    if (nResult != 0)
    {
    closesocket(s);
    return 0;
    }
    //
    //将新建立的套接字与完成端口相关联
    //

    if (CreateIoCompletionPort((HANDLE)s, g_hIOCP, (ULONG_PTR)0, 0) == NULL)
    {
    closesocket(s);
    return 0;
    } lpCommonObject = IOCOMP_GetCommonObjectNode();
    if (lpCommonObject == NULL)
    {
    closesocket(s);
    return 0;
    } lpCommonObject->sClient = s; strcpy(lpCommonObject->chClientAddr, pszRemoteIPAddr);
    lpCommonObject->nClientPort = uRemotePort;
    IOCOMP_CreateSocketID(lpCommonObject);
    InterlockedExchangeAdd(&g_lConnectedNum, 1); return lpCommonObject->dwSocketID;
    }// end of IOCOMP_Connect
      

  37.   

    我的写程序方法就是<<我是一只鱼>>自由的游来游去.没有规则就是我的规则.
    ===================================传说中的无招胜有招?
      

  38.   

    看看MFC的源代码,喜欢MFC的编码风格
      

  39.   

    写程序的时候都是两个大括号一起输入,避免少了大括号。__________________我都是需要成对使用的符号一起输入的。:)
    ===============================================
    我把所有必须有所呼应的都一起写,包括与具体函数有关的。比如
    _pRs->Open();
    _pRs->Close();
    中间再加代码,当然,类似的还有许多。