C++における異クラス間で共通して利用できるEnum型の設計について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
うにお

C++における異クラス間で共通して利用できるEnum型の設計について

#1

投稿記事 by うにお » 4年前

お世話になっております。
以前、こちらにてC++の質問をさせていただきました者です。
現在、業務にてライブラリ設計/実装を任され、設計にてつまづいてしまったので、質問させていただきたく思っております。
環境はVC++2010です。
私自身のプログラミング経験は1年ほどC#に携わっていた程度です。

件名にもあるように、現在はC++で開発を行わなくてはならなくなり、プロジェクト全体で使用するEnum型の設計に困っています。
プロジェクトの構成は、

・1クラスにつき.hファイルと.cppファイルの対を作成
・基本的には、DtoクラスとHelperクラスの2つに大別
・Dtoクラスは必要な変数ひとまとまりの構造体のような役割+α
・Helperクラスはstaticな便利メソッドの集合体
・Dto, Helperクラスはそれぞれ複数個存在し、使用する際は#include

となっている中で、自分で定義したEnum型の変数をDtoクラスやHelperクラスに共通して利用させたい、というのが現在の状況です。

仮に自分で定義したEnum型をMyTypeだとすると、簡単にコードを記述(略多め)して、

コード:

/***********************
    Helper.h
***********************/
class Helper {
    public:
        /** MyTypeを返却 */
        static MyType hoge();
    private:
        /** 実装禁止 */
        Helper();
        /** 実装禁止 */
        ~Helper();
};

コード:

/***********************
    Helper.cpp
***********************/
MyType Helper::hoge() {
    MyType mType;
    /** 省略 */
    return mType;
}

コード:

/***********************
    Dto.h
***********************/
class Dto {
        public:
        /** コンストラクタ */
        Dto( MyType, MyType );
        /** データ出力 */
        void output();
    private:
        /** 1番目のMyType */
        MyType first;
        /** 2番目のMyType */
        MyType second;
};

コード:

/***********************
    Helper.cpp
***********************/
Dto::Dto( MyType m1, MyType m2 ) {
    first = m1;
    second = m2;
}

Dto::output() {
    /** first, secondで条件分岐する何かの処理(省略) */
}
といったイメージです。
このような構成を実現させるために、enum class MyTypeをメンバに持つクラスを考えました。

コード:

/***********************
    TypeEnum.h
***********************/
class TypeEnum {
    public:
        /** 共通Enum */
        enum class MyType {
            right,
            center,
            left,
        };
        /** 文字列をMyTypeへ変換 */
        static MyType stringToMyType( const string );
};

コード:

/***********************
    TypeEnum.h
***********************/
TypeEnum::MyType TypeEnum::stringToMyType( const string str ) {
    /** 省略 */
}
このクラスを用いて2パターン考えましたが、どちらもうまくいきません…。

▪️1. 全ファイルに#includeさせる
→多重includeとなりコンパイル不可

▪️2. class TypeEnumから継承させて利用する
→複数のクラスにTypeEnumを継承させようとするとclass TypeEnumの再定義…云々のエラーが発生しコンパイル不可


▪️2. についてはイマイチなぜエラーになるのか釈然としていない、といった状況です(C#ではできたはずなので…)。
大変長くなってしまいましたが、上記のような設計を実現するための良い方法がありましたら、是非お教え頂けると幸いです。

C++はまだ2ヶ月も触っていないため、とんちんかんなことを言っていたら申し訳ございません。
何卒よろしく御願い致します。

うにお

Re: C++における異クラス間で共通して利用できるEnum型の設計について

#2

投稿記事 by うにお » 4年前

すみません、投稿してからミスに気がつきました。

上から4つ目のソースコードのヘッダコメントはHelper.cppではなくDto.cpp、
いちばん下のソースコードのヘッダコメントはTypeEnum.hではなくTypeEnum.cppでした。

ご迷惑をおかけして申し訳ありませんが、何卒宜しく御願いいたします。

アバター
lriki
記事: 88
登録日時: 9年前

Re: C++における異クラス間で共通して利用できるEnum型の設計について

#3

投稿記事 by lriki » 4年前

張っていただいたソースコードは略多めとありますが、インクルードガードはされていますか?

うにお

Re: C++における異クラス間で共通して利用できるEnum型の設計について

#4

投稿記事 by うにお » 4年前

lriki 様

ご返信ありがとうございます。
インクルードガード、していないようです…。
インクルードガードという単語を初めて聞いたので、調べてみようと思います。

質問を続けて申し訳ないのですが、インクルードガードすることによって、
当該につきましてはどのような問題が解決するのでしょうか…?
明日にならないと開発環境に触れないものでして…。

お手数ですが、宜しく御願いいたします。

アバター
lriki
記事: 88
登録日時: 9年前

Re: C++における異クラス間で共通して利用できるEnum型の設計について

#5

投稿記事 by lriki » 4年前

「1. 全ファイルに#includeさせる」の問題が解決するはずです。(それに伴って2.も解決するかもしれません)
原理理論は「インクルードガード」で検索していただければ情報が得られます。

C/C++ で組むときは .h ファイルの先頭に「#pragma once」と書く癖を付けておくと問題の予防になります。

C# とは構文こそ似ていますが、言語仕様まで一緒にしないように気を付けてください。
まして業務ということですので、「C++ 問題点」「C++ 落とし穴」などで検索してヒットする情報には一通り目を通すことをお勧めします。

うにお

Re: C++における異クラス間で共通して利用できるEnum型の設計について

#6

投稿記事 by うにお » 4年前

lriki 様

ご返信ありがとうございます。

早速インクルードガードしたところ、ご教授の通り問題が解決できました。
ありがとうございます。
(どうも、多重インクルードに関して勘違いをしていたようでした。)

また、■2. の方面も試してみまして、インクルード関連のエラーは解消されたのですが、
プライベートコンストラクタ/デコンストラクタの宣言により、
そもそもメンバであるenum classまでインスタンスを作れなくなるという別の不都合が生じたため、
今回は■1. の方法で進みたいと思います。

大変勉強になりました。
C++について更に理解を深めていこうと思います。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る