2017-04-22 12 views
0

私はいくつかの方法で関連するゲームオブジェクトの多くの型を持っています。
すべての関係はMap<K1,K2>によって実装されています。ここで戻り値の型を決定するためにenumを使用します(マクロを使用したハック)

#include <vector> 
using namespace std; 

template<class K1,class K2> class Map{ //N:N relation 
    public: std::vector<K2*> getK2(K1* k1){/* some code */return std::vector<K2*>();} 
    public: std::vector<K1*> getK1(K2* k2){/* some code */return std::vector<K1*>();} 
    //... various function ... 
}; 

は、すべての関係クエリを容易にハブクラスGameRelationです: -
(単なる例、すべての細部に注意を払う必要はありません)

class Human{}; class House{}; class Dog{}; 
class GameRelation{ 
    public: 
    #define RELATION(A,B,EnumName) Map<A,B> Map##EnumName; \ 
    enum EnumName##Enum{EnumName}; \ 
    std::vector<B*> getAllRight(EnumName##Enum e,A* a){ \ 
     return Map##EnumName.getK2(a); \ 
    } 
    //... various function ... 
    RELATION(Human,House,Own) 
    //I can insert any relation that I want 
}; 

上記のマクロは次のように展開: - ここに

Map<Human,House> MapOwn; 
enum OwnEnum{Own}; 
std::vector<House*> getAllRight(OwnEnum e,Human* a){ 
    return MapOwn.getK2(a); 
} 

は、それが(full demo)を使用することができる方法である: -

int main() { 
    GameRelation gameRelation; 
    std::vector<House*> houses=gameRelation.getAllRight(GameRelation::Own,new Human()); 
    //get all "House" that is "Own" by a "Human" 
    return 0; 
} 

いくつかのテストの後、正常に動作します。誰もが魔法の結果に満足しています。

しかし、私の意識は、それはハックだと私に教えてください。
コンテンツアシスト(例:インテリセンス)や自動リファクタリングには少し悪いこともあります。
また、実装を.cppに移動する場合は、素晴らしいハッキングX-MACROが必要です。

質問:

  • 任意のエレガント(以下ハック)方法はありますか?それは何ですか?
    「いいえ」は有効な回答です。
  • X-MACRO私はそのような(奇妙な)機能が必要なときに行く(プロフェッショナルな)方法ですか?
+1

'using namespace std;'?あなたはそれより優れています... – Quentin

+0

あなたは、命令型プログラミング言語で列挙型とマクロを使ってリレーショナルデータモデルを再開発しようとしているようです。あなたは代わりにSQLiteのようなものを使用することを考えましたか?あなたはテーブル「家」、テーブル「人間」、前の2つの外部キーを持つテーブル「house_ownership」を持つことができます。 –

+0

@Quentin同意します。これはデモのためです。これは「ideone」のデフォルト設定です。 – javaLover

答えて

1
struct GameRelation{ 
    template <typename A, typename B> 
    struct Relation { 
     std::vector<B*> getAllRight(A* a) { 
      return map.getK2(a); 
     } 

    private: 
     Map<A, B> map; 
    }; 

    Relation<Human, House> own; 
}; 

int main() { 
    GameRelation gameRelation; 
    std::vector<House*> houses = gameRelation.own.getAllRight(new Human()); 
} 
+0

それは正しい方法が好きです。 – javaLover

+0

私が見つけた唯一の(マイナーな)不利な点は、カプセル化されていないということです。フィールド "own"に直接アクセスします。 – javaLover

+1

@javaLoverなぜこれが問題ですか?'Relation'は特にアクセサーであることを意図しており、その上の望ましくない操作は単にそれらを提供しないことによって禁止することができます。 –

関連する問題