1

次の行に沿って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::これは可能ですか?

4

5 に答える 5

7

はい、そして非常に簡単です。クラス内にsが必要ない場合は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);
// ...
};
于 2012-08-14T18:41:16.390 に答える
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, ...);
}
于 2012-08-14T18:56:52.093 に答える
1

クラス外で列挙型を定義し、繰り返しを避け、列挙型名が衝突するリスクを避けたい場合は、C++11のenum class可能性も考慮してください。

LuchianGrigoreサンプルの再作成

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

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

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

Button::Yesこれで、などのように列挙型を明示的に修飾することによって列挙型を使用するようにIcon::Question強制され、intに明示的にキャストすることも強制されます(暗黙の変換は存在しません)

于 2012-08-14T19:41:35.930 に答える
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型を短い便利な識別子に変換し、これを資格として使用します(ハッキー)

  • 必要に応じて個々の定数を名前空間にコピーする(面倒)

  • ...?

于 2012-08-14T18:46:45.140 に答える
0

別のオプションは、ウィジェットに関連する完全に異なる名前空間に列挙型を配置することです。Qtたとえば、図書館はそうします。Qtそれらを特定のクラスに配置する代わりに、名前空間に多くの列挙型を配置します

于 2012-08-14T18:55:24.937 に答える