我可以避免由特定类定义的限定名称吗?

时间:2012-08-14 18:39:23

标签: c++ class enums scope naming

假设我有以下几行的MessageBox类:

class MyMessageBox
{
public:
    enum Priority {
        Prior_Dialog,
        Prior_Warning,
        // ...
    };

    enum Icon {
        Icon_Question,
        Icon_Exclamation,
        // ...
    };

    enum Button {
        Button_Yes,
        Button_No,
        Button_Cancel,
        // ...
    };

    static void Show(Priority pPriority, Icon pIcon, Button pButton1, Button pButton2);

    // ...
};

现在,如果我想抛出一个消息框,我必须为每个标识符键入MyMessageBox::

MyMessageBox::Show(MyMessageBox::Prior_Dialog, MyMessageBox::Icon_Question, MyMessageBox::Button_Yes, MyMessageBox::Button_No);

理想情况下,我想要一些非宏解决方案,允许#include "MyMessageBox.h"在任何地方省略MyMessageBox::资格的源文件。这可能吗?

5 个答案:

答案 0 :(得分:7)

是的,非常简单。如果你不想在课堂上enum,那么......不要在课堂上定义它们。

enum Priority {
    Prior_Dialog,
    Prior_Warning,
    // ...
};

enum Icon {
    Icon_Question,
    Icon_Exclamation,
    // ...
};

enum Button {
    Button_Yes,
    Button_No,
    Button_Cancel,
    // ...
};

class MyMessageBox
{
public:
    static void Show(Priority pPriority, Icon pIcon, Button pButton1, Button pButton2);
// ...
};

答案 1 :(得分:4)

如果枚举和类在单独的命名空间中声明(即枚举应在类外声明)只是不污染全局命名空间

namespace MessageBoxUtils {

enum Priority {
    Prior_Dialog,
    Prior_Warning,
    // ...
};

enum Icon {
    Icon_Question,
    Icon_Exclamation,
    // ...
};

enum Button {
    Button_Yes,
    Button_No,
    Button_Cancel,
    // ...
};

class MyMessageBox
{
public:
    static void Show(Priority pPriority, Icon pIcon, Button pButton1, Button pButton2);

    // ...
};

} // namespace MessageBoxUtils

客户端代码(某些cpp文件):

#include ...

using namespace MessageBoxUtils;

...

void SomeClass::Foo()
{
    MyMessageBox::Show(Prior_Dialog, Icon_Question, ...);
}

答案 2 :(得分:1)

如果你想定义类外的枚举,并且你也希望避免重复并避免枚举名称冲突的风险,那么也要考虑C ++ 11 enum class的可能性:

重新阐述Luchian Grigore样本

enum class Priority {
    Dialog,
    Warning,
    // ...
};

enum class Icon {
    Question,
    Exclamation,
    // ...
};

enum class Button {
    Yes,
    No,
    Cancel,
    // ...
};

您现在被迫通过显式限定它们来使用枚举,例如Button::YesIcon::Question等,并且您也被迫显式转换为int(不存在隐式转换)

答案 3 :(得分:0)

您无法通过using关键字将标识符“导入”全局命名空间:

using MyMessageBox::Prior_Dialog; // won't work

(文档的第一眼误导我:http://msdn.microsoft.com/en-us/library/was37tzw%28v=vs.80%29.aspx

仍然,我建议将它们所属的枚举留在MessageBox类中。这避免了混淆和模糊 - 其他人可以定义相同的枚举项但为其分配不同的值,从而导致编译错误。

或者,您可以将类更改为命名空间,然后使用using“加载”标识符(甚至整个命名空间,如果您愿意)。

其他可能的快捷方式包括:

  • typedef类中的枚举MessageBox转换为简短的方便标识符并将其用作限定条件(hacky)

  • 在需要时将个别常量复制到命名空间中(繁琐)

  • ...

答案 4 :(得分:0)

另一种选择是将你的枚举放入与你的小部件相关的完全不同的命名空间。例如,Qt库这样做。他们在Qt命名空间中放了很多枚举,而不是将它们放在特定的类