void.pointer
void.pointer

Reputation: 26335

Need design advice for exclusive access to private class state

I have a simple system I'm working on that involves serializing user objects. I have a series of specialized template classes that act on each type to be read/write differently:

template<class T>
class ItemSerializer;

template<>
class ItemSerializer<int>
{
public:
    static void store( int const& obj )
    {
    }

    static void fetch( int& obj )
    {
    }
};

template<>
class ItemSerializer<NoteNumberArray>
{
public:
    static void store( NoteNumberArray const& obj )
    {
       // NoteNumberArray::_blocks is used here.
    }

    static void fetch( NoteNumberArray& obj )
    {
       // NoteNumberArray::_blocks is used here.
    }
};

Depending on the type, it may or may not have state with it, which is necessary for the serializer class to which it is assigned. In this example, I have serializers for 2 types: int and NoteNumberArray. The store/fetch functions do not need any additional state for int types, the read/write implementation is very simple.

However, for NoteNumberArray, state is necessary so I create my own class instead of using core types or STL types. This state is used by the implementation of ItemSerializer only, for optimization purposes. This private state would be used to optimize the speed and efficiency of the read/write methods. Since the serializer classes are not stateful, I put this state in the user object instead.

I could probably make ItemSerializer a friend of NoteNumberArray, but this would cause a circular dependency and gives ItemSerializer access to more of NoteNumberArray than might be necessary.

What is a good design for such a system? Just looking for some tips to help me get started. Here is some other relevant snippets for this example:

class Block
{
};

class NoteNumberArray
{
public:
    // Public interface, none of which will use _blocks. Only ItemSerializer uses _blocks.

private:
    std::vector<int> _array; // This should not be used directly by anyone, including ItemSerializer.
    std::vector<Block> _blocks; // This is the private state only used by ItemSerializer
};

Upvotes: 1

Views: 145

Answers (2)

Chris Hartman
Chris Hartman

Reputation: 177

I don't see the circular dependency problem, there is no dependency issue making ItemSerializer<NoteNumberArray> a friend of NoteNumberArray.

I do see the access issue if you don't want ItemSerializer<NoteNumberArray> to be able to see other private parts of NoteNumberArray.

One possibility is to wrap _blocks into another class NoteNumberArraySerializerHelper, which has ItemSerializer<NoteNumberArray> as a friend and all methods (including constructors and other things that would normally be written for you by the compiler) private. Then you'd have to give public accessor/mutator methods for _blocks to NoteNumberArray but nobody except ItemSerializer<NoteNumberArray> could use those methods to do anything.

Upvotes: 2

Mark B
Mark B

Reputation: 96243

If _blocks is only used by ItemSerializer just make it a member of the ItemSerializer specialization instead. Without understanding the whole purpose, I can't see the advantage of storing such a thing in the NoteNumberArray directly.

As a side note, by avoiding leading _ on your identifiers you can easily avoid accidentally using reserved names (such as _ followed by capital or leading _ in the global namespace).

Upvotes: 0

Related Questions