2

I need to write a factory in C++03 that works like so:

1) The elements created are blocks of objects

2) The factory saves references to all such sub-objects.

3) The blocks are scale-able

Meaning:

class Block{
     MemberType member1;
     MemberType member2;
     MemberType member3;
     Block(){...}
}

class Factory{
     set<MemberType*> members1;
     set<MemberType*> members2;
     set<MemberType*> members3;

     Block& makeBlockInstance(){
           Block& currentBlock = *(new Block());

           members1.push_back(&(currentBlock.member1));
           members2.push_back(&(currentBlock.member2));
           members3.push_back(&(currentBlock.member3)); 

           return currentBlock;
     }
}
  • please don't mind syntax errors or minor details, the code is to make a point.

What I need is a way to add or remove members from Block, in such a way that would AUTOMATICALLY create or delete the set<MemberType*> members#, and the members#.push_back(...).

Is this possible? It seems like something that is done via reflection, but I want some non-reflection way of doing this, statically.


I would love to see a non- preprocessor way of doing this.

Until then (if at all) - here is how to make the X macro expansion conditional C++ preprocessor conditional parameter

Community
  • 1
  • 1
Gulzar
  • 23,452
  • 27
  • 113
  • 201
  • For comparison, the C++11 version [here](http://stackoverflow.com/questions/31724320/c-smart-factory-design). – Jarod42 Aug 10 '15 at 12:37
  • I don't much care if it is std::set or some other iterable sorted container (is there such a thing?). If you could show me what you would do, I would be delighted. Thanks – Gulzar Aug 10 '15 at 12:43

1 Answers1

4

I think the cleanest way is using a X Macro implementation:

#define MEMBERS \
X(member1)
X(member2)

#define X(m) MemberType m;
MEMBERS
#undefine X

#define X(m) set<MemberType*> m;
MEMBERS
#undefine X

#define X(m) m.push_back(&(currentBlock.m));
MEMBERS
#undefine X

If you would like the members to have different types you can change it to:

#define MEMBERS \
X(int, member1)
X(vector<char>, member2)

#define X(t, m) t m;
MEMBERS
#undefine X

#define X(t, m) set<t *> m;
MEMBERS
#undefine X

#define X(t, m) m.push_back(&(currentBlock.m));
MEMBERS
#undefine X
RedX
  • 14,749
  • 1
  • 53
  • 76
  • You do not need any concatenation (and, in fact, it won't work); `m`, `.`, `push_back` and `currentBlock` are already separate tokens. So just write `m.push_back(&(currentBlock.m));` Remember that this is the same as `m . push_back ( & ( currentBlock . m ) ) ;`. Macros don't create source code; they create tokens. – Lightness Races in Orbit Aug 10 '15 at 12:46
  • This is a rather satisfying answer, I hope this will prove to be what I really need. Thanks! Just out of curiosity - could you think of any non-preprocessor-magic method for doing this? – Gulzar Aug 10 '15 at 20:57
  • what if i need more than one type? I would need a different MEMBERS list for each type? how would I combine them all into one? – Gulzar Aug 11 '15 at 04:54
  • I implemented this concept into my code, and it works just fine. Saws everything together, and looks nice. However, i fear the non-standardness of it, and thd fact that it is preprocessor oriented, thus the one who will come after me won't be able to debug this. Could you recommend a non-preprocessor way to do just this? Thanks – Gulzar Aug 18 '15 at 15:36