开发者

better than enum

I've a lot of data and inside a loop I need to put a selection. Every entry is a physics event. In every event there is only one particle with its properties:

for (...)   {  // loop over entries in the data
    if (not selection()) continue;
    ...
}

From the command line I select a particular type of particle to be considered, for example:

Options options = get_options(argc, argv);

enum ParticleType_type {ELE, PHO, ...}

cout << "particle: " << get_particle_name(options.particle_type);

for (entry in data) { // loop over data
    // read variale like PDG, conv, ... for the entry
    switch (options.particle_type)
    {
          case ELE: if (PDG != 11) continue; break;
          case PHO: if (PDG != 22) continue; break;
          case PHO_UNC:   if (PDG != 22 or conv) continue; break;
          case PHO_CONV:  if (PDG != 22 or !conv) continue; break;
          case PHO_1TRK:  if (PDG != 22 or !conv or !is1trak) continue; break;
          case PHO_2TRK:  if (PDG != 22 or !conv or !is2trak) continue; break;
          case PHOR1:     if (PDG != 22 or !conv or !(r>0 and <=200) continue; break;
          case PHOR2:     if (PDG != 22 or !conv or !(r>200 and &l开发者_JAVA技巧t;=400) continue; break;
          case PHOR3:     if (PDG != 22 or !conv or !(r>400 and <=600) continue; break;
          case PHOR4:     if (PDG != 22 or !conv or !(r>600 and <=800) continue; break;
    }

    do_something();

    if (isPhoton(options.particle_type)) // true for every PHO_XXX
    {
         if (options.particle_type in [PHORX])
         {
              int rbin = get_Rbin(options.particle_type) // PHOR1 -> 1, PHOR2 -> 2
              ...
         }  
         ...
    }
}

cout << "output: " << get_file_name(options.particle_type) + ".out";

as you can see:

  1. is't a mess
  2. there are subcategories, for example PHO_CONV is a PHO and PHO_1TRK is a PHO_CONV
  3. every ParticleType_type has some properties, like the name, the file_name and more
  4. now I need to double the categories like PHORx using r step of 100 and not 200. I want to parametrize the range in some way, probably using template argument somewhere
  5. I need to cross the categories for example creating PHOR1_1TRK
  6. (less relevant) I'm dominating by I/O. Presently if I want to process PHO and ELE I need to run twice, I want to do them at the same time

I think the best solution is to create one class for every ParticleType_type, and put function like get_file_name as member functions. The problem is that class are not object so I can't pass them as an argument of a function: for example with enum now I can write free function that take ParType_type as an argument, but with classes I can't.

I want to create automatically parametric types, for example PHORX.

Can someone suggest some tecniques?


The Flyweight pattern might be useful for you here.

Instead of having an instance for each particle with an enum of its type, you would have one single instance of each particle type and a pointer to this instance for each particle of that type. The particle type would take a pointer to your particle struct for computations.

e.g.

// pseudocode!
ParticleA a;
ParticleB b;

struct ParticleData {
  Particle * type;
  int data;
} particles[] = {
  { &a, 5 },
  { &a, 7 },
  { &b, 4 },
 // ... 
};

for each( particle in particles ) {
  particle->type->do_something(particle);
}


Creating classes (subclasses of a (possibly abstract) particle class) for each particle type looks like the right approach.

You wouldn't be passing a class to a function, you'd be passing an instance of that class.


Instead of writing separate classes for all your particles you could use a table-driven method (see e.g. here).

You would create a table which uses a ParticleType_type as index to get a function pointer or boost::function that does the particle-specific processing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜