C++设计开发规范(4):成员设计规范

来源:互联网 发布:高质量java程序设计 编辑:程序博客网 时间:2024/06/04 17:51
  
4.    成员设计规范
4.1.   一般规范
要求重载成员之间的相同参数的顺序和名称要一致。
    例如,
       class EventLog
       {
       public:
              EventLog();
EventLog(const string& logName);
EventLog(const string& logName, const string& machineName);
       }
× 不要在重载中随意地给参数命名。
要求在成员方法的签名添加”const”,如果成员方法不需要改变对象的状态。
    例如,
       class DocumentEnvironment
       {
       public:
              const std::string& GetAuthor(){…}//不好
const std::string& GetAuthor() const{…}//好
       }
× 不要对参数为指针和数字类型的函数进行重载。
    例如,
       class StockHolder
       {
       public:
              void SearchStock(int stockCode);
void SearchStock(const wchar_t* stockName);
       }
       //如果按照下面的方式调用
       StockHolder stockholder;
       Stockholder. SearchStock(0);//调用存在二义性
要求优先使用重载,而不是定义具有默认参数的成员。
    例如,
       class Point
       {
       public:
              void Move(int x,int y=0){…}//不好
              //
void Move(int x){…}
void Move(int x,int y){…}
       }
要求优先使用重载,而不是定义具有默认参数的成员。
要求对短小的函数合理使用inline。
× 不要定义inline virtual的成员函数。
       例如,
       class Point
       {
       public:
              inline virtual void Move(int x,int y=0){…}//不好
              void Move(int x,int y=0){…}//
virtual void Move(int x,int y=0){…}//好
}
4.2.   构造/析构函数的设计
要求在构造函数中作最少的事情且不要在构造函数中抛出异常。
l 推荐避免在构造函数中出现隐式赋值。
       例如,
       class A
{
public:
       A(int a){..}    //不好
       explicit A(int a){..} //
}
要求重新编写/禁用拷贝构造函数和operator=重载
如果编译器生成的拷贝构造函数和operator=重载不是所期望的:如果需要这两个操作,重新编写这两个函数;否则,显示地禁用它们。
    例如,
    //显示地禁用拷贝构造函数和operator=重载
       class Envidence
       {
       private:
              Envidence(const Envidence& other){…}
Envidence& operator=(const Envidence& other){…}
}
要求使将基类析构函数设为public且virtual,或设为protect而非virtual。
如果允许通过指向基类Base的指针执行删除操作,那么将基类析构函数设为public且virtual,或设为protect而非virtual。
例如,
class AuthrizationStrategy
{
public:
AuthrizationStrategy();
         virtual AuthrizationStrategy();
};
class LogonSession
{
public:
LogonSession ();
protected:
         LogonSession ();
};
4.3.   操作符重载
要求以对称的方式重载操作符
例如,如果重载了operator==,那么应该同时重载operator!=。同样,如果重载了operator<,那么应该同时重载operator>。
× 不要提供类型转换操作符,如果没有明确的需求。
× 不要提供隐式类型转换操作符,如果该类型转换可能会丢失精度。
例如,由于double的覆盖范围比int要广,因此不应该存在把double隐式地转换为int的操作符。即使类型转换可能会丢失精度,也可以提供显式的类型转换操作符。
4.4.   字段的设计
l 推荐在结构中提供public字段(默认)
     例如,
     struct PageSetting
     {
            int PageCount;
            int LeftMargin;
            …
}
× 不要在类中不要提供public/protected字段
例如,
class ChangeManager
{
public:
       ChangeManager(int changeType, int changeEvent)
              : m_changeType(changeType),
         m_changeEvent (changeEvent),
{…}
int GetChangeType() const{return m_changeType ;}
int GetChangeEvent () const{return m_changeEvent;}
private:
       int m_changeType;
       int m_changeEvent;
}
4.5.   参数的设计
× 不要使用保留参数。
例如,
       //不好
       void Method(SomeOption option,object reserved)
//不好
       void Method(SomeOption option)
l 推荐将所有的引用/返回参数放到函数签名的后面,这样可以使函数签                       名更易于理解。
       例如,
       bool GetObjectFromID(VOBJID32 oidObject,vtl::Cv_PTR& objReturned);
       void CreateNullSpreadItem(VCLSID clsidProxy,VOBJID32& oidNewSpreadItem);
要求在重载函数或实现接口函数时保持参数命名的一致性。
    例如,
       //重载时
       bool Equals(const string& value);
       bool Equals(const string& value,bool ignoreCase); //
       bool Equals(const string& other,bool ignoreCase); //不好
//实现接口时
       public ISpreadItem
       {
              virtual bool Transform(const Matrix& matrix) = 0;
       }
       classs SpreadItem : public ISpreadItem
{
public :
       bool Transform(const Matrix& matrix); //
       bool Transform(const Matrix& trasformMatrix); //不好
}
l 推荐不要使用不定长的参数。
       例如,
       class StringUtil
       {
              string Format(const wchar_t* format,…);//不推荐
}
× 不要使参数长度超过一定的数量(7个以内)。
要求对于不会被改变的简单类型的参数使用值传递,而不是使用引用传递。
       例如,
       void ShowMessage(const std::string& message,int option);//
void ShowMessage(const std::string& message,const int& option);//不好
void ShowMessage(const std::string& message,const int option);//不好
要求对于不会被改变的复合类型的参数使用引用传递,而不是使用值传递。
       例如,
       void Log(const std::string& message,const Color& backgroundColor);//
void Log(std::string message, Color backgroundColor);//不好
4.6.   返回值的设计
× 不要返回字段的非const引用,除非完全必要。
       例如,
       class PhoneBook
       {
       public:
              Address& GetAddress() const{return m_address ;}//不好
              const Address& GetAddress() const{return m_address ;}//
       private:
              Address m_address;
}
要求返回字段的const引用。
       Class  Document
       {
       public:
              const DocumentInfo& GetAddress() const{return m_documentInfo;} //
              const string& GetAddress() const{return m_fileName;}//
              //
              const wchar_t* GetAddress() const{return m_fileName;}//
       private:
              DocumentInfo m_documentInfo;
              string m_fileName;
}
4.7.   全局变量/函数/常量/宏的设计
× 不要使用全局变量和函数,将全局变量和函数作为某个类的静态成员函数。
    例如,
       //不好
extern void ToCMYKColor (Color& color);
extern void ToRGBColor(Color& color);
//好
class ColorConverter
{
public:
static void ToCMYKColor (Color& color);
static void ToRGBColor(Color& color);
}
× 不要使用”Magic Number”,使用const修饰符来进行定义。
× 不要使用#define来定义常量,应该使用const修饰符或采用enum来定义常量。
    例如,
       //不好
#define FITUNKNOWNBLOCK 0
       #define FITPICTUREBLOCK      1
       #define FITTEXTBLOCK           2
//好
enum kFitBlockType
{
kFitBlockType_Unknown,
              kFitBlockType_Picture,
              kFitBlockType_Text
}