C ++如何用consts替换#defines

时间:2013-06-08 01:49:55

标签: c++ const c-preprocessor

最近我一直在仔细研究我的编程风格以及如何改进它。首先让我说,在我目前的职位上,我是唯一的程序员。因此,我可以按照自己的意愿做事,但我真的很努力成为一个更好,更健全的程序员。

另外,我的背景主要是基于C的,基本上在必要时使用C ++作为C的超集。结果,我偶然发现了以下难题。

我总是用#define ERROR_FUNCTION_BLEW_UP -2定义错误代码。诚实地说,我可以看到这样做的好处,因为我不需要分配内存来存储-2。但是,在C ++中我可以看到使用const变量的好处,因为两个竞争宏之间碰撞的可能性更小。

结果,我想知道在C ++中实现错误代码的最简洁方法是什么。也就是说,我希望客户端能够通过执行类似于“if(return_value == ERROR_FUNCTION_BLEW_UP)”的操作来检查某些函数的返回值。我已经尝试在每个类中添加一个const变量,但是代码看起来不正确。也就是说,客户端现在检查“if(return_value == MyClass.kErrorFunctionBlewUp_)”行。是否有更简洁的方法来实现这一点,而不是让常数成为班上的公共成员?

另外,要添加到我的问题,myClass是一个基类,现在我想在MyDerivedClass中添加更多错误代码。有什么办法解决这个问题并避免使用宏?

谢谢大家的帮助。

2 个答案:

答案 0 :(得分:6)

使用enum s:

enum Errors
{
    NO_ERROR = 0,
    FUNCTION_BLEW_UP,
    WTF_THIS_SHOULDNT_HAPPEN,
};

另外,如果它们更合适,请考虑使用例外(查看std::exception)。

答案 1 :(得分:0)

如果您真的只想更换宏,请用常量替换它们。常量具有内部链接(即限于转换单元(“文件”)),因此编译器可以很容易地仅使用常量内联替换它们的使用,而不使用比宏更多或更少的单个字节。请注意,习惯上将ALL_UPPERCASE保留为宏,因为宏不遵循常规代码约定,因此您也必须更改它。

然后,在C ++中,您通常不使用调用者必须检查的返回代码,而是使用自动传播的异常。如果要保留错误代码,可以使用枚举或常量并将它们放入命名空间。请注意,枚举会泄漏到周围的命名空间或类中,因此最好将它们包装在一个级别:

namespace errorcode
{
    enum type
    {
        printer_on_fire,
        volume_not_formatted,
        bluescreen
    };
}

异常有时会包含错误代码,这些错误代码会进一步指明失败的内容。这是指定它们的一种方法:

struct error:
    std::runtime_error
{
    ...

    enum code
    {
        printer_on_fire,
        volume_not_formatted,
        bluescreen
    };

    code fault;
};

请注意,您不必嵌套代码,也可以使用上面的现有errorcode::type构建异常类型。但是,有些嵌套很有用,因为枚举会污染周围的命名空间。

那就是说,你问“在课前把它放在文件的顶部”,但是你有一个误解。首先,并非每个文件都包含一个类。然后,并非每个包含类的文件都包含其中一个。例如,如果整个类层次结构使用了错误代码集合,则在单独的文件中定义它是有意义的,以明确它不仅属于其中一个并且可以在相关的非类中使用功能也是。在那个文件中,你也会坚持,例如用于将其转换为字符串以进行调试的函数,也可能是携带其中一个的异常类型。