Gulzar
Gulzar

Reputation: 27966

C++ Smart Factory Design

Not c++11

I need to write a Factory in c++ 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;
     }
}

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.

Thanks.

Upvotes: 0

Views: 201

Answers (1)

Jarod42
Jarod42

Reputation: 217478

Following may help:

template<typename ... Ts> struct BlockFactoryT;

template<typename ... Ts>
struct BlockT
{
    using Factory = BlockFactoryT<Ts...>;

    BlockT(){...}

    std::tuple<Ts...> members;
};

template<Ts...>
struct BlockFactoryT{
    using Block = BlockT<Ts...>;
    std::tuple<set<Ts*>> members_sets;

    std::unique_ptr<Block> makeBlockInstance()
    {
        return makeBlockInstanceImpl(std::index_sequence_for<Ts...>());
    }

    template<std::size_t ... Is>
    std::unique_ptr<Block> makeBlockInstanceImpl(std::index_sequence<Is...>)
    {
        auto block = std::make_unique<Block>();

        const int dummy[] = {0,
            (std::get<Is>(members_sets).insert(&std::get<Is>(block->members)), 0)...};
        static_cast<void>(dummy); // Remove warning for unused variable
        return block;
    }
};

And for simplicity:

using MyBlock = BlockT<MemberType, MemberType, MemberType2>;
using MyFactory = typename MyBlockT::Factory;

Upvotes: 2

Related Questions