对决:enum VS const

来源:互联网 发布:重庆市近几年物流数据 编辑:程序博客网 时间:2024/04/27 20:27

原文标题:enum vs const

原文作者:Rob Manderson

原文出处:http://www.codeproject.com/cpp/enumvsconst.asp

译文作者:xlander

 

最近我负责对别人写的一些C++代码进行复查,代码检查能够引起错误的条件,如果一旦发生错误的话,就进行一些合情合理的善后措施。写的很好,不过,就又那么一个小地方让我郁闷的不得了。

由于某些原因,我这里不方便把真实的类展示出来,为类方便问题的说明,我们来人为地杜撰一个。

 

我所复查的类大概如下:

 

class CAClass

{

public:

    const UINT aConstantOfInterestToThisClass1 = 0;

    const UINT aConstantOfInterestToThisClass2 = 1;

 

    CAClass(UINT constValue, LPCTSTR someOtherParameter);

 

    void DoSomething();

 

private:

    UINT    m_const;

    CString m_parameter;

};

 

CAClass的构造函数传入一个它感兴趣的常量参数和一个字符串指针。DoSomething()根据构造函数传入的参数做一些处理。该类的实现代码如下:

 

CAClass::CAClass(UINT constValue, LPCTSTR someOtherParameter)

{

    m_const = constValue;

    m_parameter = someOtherParameter;

}

   

void CAClass::DoSomething()

{

    switch (m_const)

    {

    case aConstantOfInterestToThisClass1:

        //  Do something defined by this constant.

        break;

 

    case aConstantOfInterestToThisClass2:

        //  Do something defined by this constant.

        break;

 

    default:

        //  It's not a valid value, raise an exception

        RaiseException(ERROR);

        break;

    }

}

 

这段代码能够正常工作,那么问题出在哪儿呢?

如果是我的话,我会怎么做?

 

class CBClass

{

public:

    enum constsOfInterestToThisClass

    {

        bConstantOfInterestToThisClass1 = 0,

        bConstantOfInterestToThisClass2 = 1,

    };

 

    CBClass(constsOfInterestToThisClass constValue,

            LPCTSTR someOtherParameter);

 

    void DoSomething();

 

private:

    constsOfInterestToThisClass m_const;

    CString m_parameter;

};

 

实现代码:

CBClass::CBClass(constsOfInterestToThisClass constValue,

                 LPCTSTR someOtherParameter)

{

    m_const = constValue;

    m_parameter = someOtherParameter;

}

   

void CBClass::DoSomething()

{

    switch (m_const)

    {

    case bConstantOfInterestToThisClass1:

        //  Do something defined by this constant.

        break;

 

    case bConstantOfInterestToThisClass2:

        //  Do something defined by this constant.

        break;

 

    default:

        //  It's not a valid value, raise an exception

        RaiseException(ERROR);

        break;

    }

}

 

这几乎没有任何差别,任何C++编译器都能够为这两个类产生相同的代码。

那么差别在哪儿呢?

 

第一个类,CAClass,为自己定义了一组常量。第二个类也定义了同样含义的一组常量,但它的形式是enumEnum可以用来定义一个包含所有合法取值的有限集合,也可被用作伪数据类型(pseudo datatype),看一眼两个构造函数的区别:

 

CAClass(UINT constValue, LPCTSTR someOtherParameter);

CBClass(constsOfInterestToThisClass constValue, LPCTSTR someOtherParameter);

 

CAClass能够接受任何合法的UINT值,在将近40亿个可能取值中,只有两个是该类所感兴趣的。任何除了01之外的UINT取值都会使DoSomething产生异常。相反,CBClass只能接受两个枚举值中的一个。传递任何非法的常量都会使编译器报出错误或警告。

 

对比一下:

CAClass obj(1000, _T("This is a string"));

obj.DoSomething();

 

CBClass obj(1000, _T("This is a string));

obj.DoSomething();

 

在第一个例子中,CAClass obj(1000,_T(“This is a string”));将正常编译,并在运行时抛出异常。而第二个例子中,CBClass obj(1000, _T("This is a string));会毫不客气的在你的编译器里产生错误信息,这样就不会产生可执行文件,直到你纠正错误并提供合法值。

CBClass的构造函数要求第一个参数的类型是constsOfInterestToThisClass,可以是bConstantOfInterestToThisClass1,也可以是bConstantOfInterestToThisClass2,还可以是constsOfInterestToThisClass类型的变量。编译器允许你定义constsOfInterestToThisClass型的变量,不过你给这个变量赋值的时候,只能使用你先前定义的枚举值。

 

constsOfInterestToThisClass var;

var = bConstantOfInterestToThisClass1;  // OK

var = 47;  // Error

 

结论:

编译器能够在编译的时候替你进行众多的错误检查,使用enum,而不是const,能够使编译器找到使用了不合适的假定条件的代码。

原创粉丝点击