C++でとあるフォーマットで記述されたファイルからクラスを生成するモノ(ローダー?)を作ろうと思っています。

どのように設計したらよいでしょうか?

私は以下の3つの方法を考えました。
1)関数呼び出し
int XXXLoadFromFile(char* ファイル名, 欲しいクラス** ppOut);
関数内部で関数を呼ぶと引数が増えてごちゃごちゃになる。

2)クラス
コンストラクタでファイル名をセットしLoadメンバ関数で読み込み。GetXXXメンバ関数で欲しいクラスの取得。

3)生成して欲しいクラス自体がLoadメンバ関数を持つ。


色々考えましたがどうもしっくりきません。

※URLを載せる場合は何故そのURLは参考になるのか?を書いてください。

回答の条件
  • 1人2回まで
  • 13歳以上
  • 登録:2010/03/21 02:33:56
  • 終了:2010/03/28 02:35:03

回答(1件)

id:pyopyopyo No.1

pyopyopyo回答回数340ベストアンサー獲得回数832010/03/21 12:00:03

ポイント60pt

こういうアプローチはいかがでしょうか?

強いて言えば、3)の方法に近いです。

class Object {
};

// ファイルから生成するクラス その1
class Object1 : public Object {
public:
   // ファイルを読んで初期化を行う。成功したら true を返す
   bool load(const char *filename);
};

// ファイルから生成するクラス その2
class Object2 : public Object {
public:
   // ファイルを読んで初期化を行う。成功したら true を返す
   bool readData(const char *filename);
};

// ローダー本体
Object* loadFromFile(const char *filename)
{
   {
      Object1 obj1 = new Object1();
      bool r = obj1->load(filename);
      if (true == r)  
        return obj1;
     
      delete obj1;
   }

   {
      Object2 obj2 = new Object2();
      bool r = obj2->readData(filename);
      if (true == r) 
        return obj2;

      delete obj2;
   }
   return NULL;
}
  • 基底クラスとしてObjectクラスを用意します。
  • ファイルから生成するクラスは、すべて Objectクラスを継承するようにします。

- Objectクラスを継承したクラスに、load() とか readData()のようなファイルを読む関数を定義します。

- load() とか readData() は読み込みに成功した場合 true を返す関数とします。

  • ファイルからインスタンスを生成する場合は loadFromFile() を使います。

- 生成に成功した場合は Object のポインタ、失敗時は NULL を返します。

実際使うときは、 Object クラスに display() とか action() のような各機能を virtual 関数として追加し、

必要に応じて派生クラス側Object1とかObject2側でオーバライドしていきます。

  • id:tdoi
    この要件だけだと、どれがいいとも、他の方法があるともいえないと思います。
    生成するものがどんなものなのか、それに対してどういう操作をしたいのか、そういった要素によって、どういうインターフェースを用意する方が都合がいいか、どういう構造にするとよいかが決定すると思います。

    もう少し具体的に言うと、

    この仕組みを使ってオブジェクトを生成する際には、そのオブジェクトの実態の型は分かっているのでしょうか?それとも、ファイルの中を解析して初めて決定されるのでしょうか?
    生成されるオブジェクトは単一でしょうか?複数あるのであれば、それらの間に関係はあるのでしょうか?あるいは、複数あるものはこれから増えることも想定されるのでしょうか?

    また、しっくりこないとは、どういうことでしょうか?

    一般的な話としては、個人的には、
    1は「関数内部で関数を呼ぶと引数が増えてごちゃごちゃになる」の意味が分かりませんが、生成するオブジェクトが1種類なら悪くないと思います。個人的にはポインタのポインタ渡すくらいなら、返り値をポインタにしてしまう方が呼び出しやすい気がしますが。
    2は状態を管理する必要がない(と思われる)のに、ファクトリオブジェクトを生成していて冗長な気がします。
    3もありだとは思います。

    あとは、

    template <typename T>
    boost::shared_ptr<T> LoadFromFile<T>(const std::string& filename);

    とか定義して、特殊化するというのもありだと思いますけどね。
  • id:mijusawa
    コメントの返信が遅れて申し訳ありません。
    結局、関数呼び出しで内部でワーク用のクラスを作ることにしました。
  • id:mijusawa
    クラスがロード関数を持つってなんか嫌なんですよね、、
    生成するクラスは外部のファイルの構造を気にする必要がないのが良いと思うんです。
    んーうまくいかない

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません