Question

I'm trying design a set a classes to store / access / analyse my data but I'm not sure how they should fit together.

Background

My (simplified) data is in the form of "events" which can be represented like this:

//Representation of my data
class Event
{
private:
vector<track> tracks_;
vector<cluster> clusters_;
};

where track and cluster have functions like get_track_time() or get_cluster_size().

I have multiple algorithms for selecting the "best" track and cluster which I want to make available to more complicated functions. I want to store this selection so that it only has to be computed once for each event.

Question

How do I store the "best" track? Below is my code storing a pointer/reference to a private member in an external object. This breaks encapsulation but I can't store a pointer inside the 'Event' class because there could be more than one definition of "best" at any one time. Do I just have to accept pointers/references to private members or is there a better way to arrange things?

My code

I was thinking of representing them with function objects, resulting in this:

//Interface for selecting a particular track
class BestTrack
{
public:
virtual void new_event(const Event& e) = 0;
virtual const& track get_track(const Event& e) = 0;
virtual ~BestTrack();
    };

//Sample implementation of track selection
class ABestTrack : public BestTrack
    {
    public:
    void new_event(const Event& e )
        { ..implementation sets cached_track... }

    const& track get_track()
    { return *cached_track; }


private:
track * cached_track; //I think this would have to be a pointer not a reference
};

which would be used by my analysis objects:

//Some complicated analysis object
class MyAnalysis
{
public:
MyAnalysis( BestTrack * bt );
void DoAnalysis( const Event& e )
{
//get the best track
auto best_track  = bt( e );
...implementation...
}
private:
BestTrack* bt;
};

So that finally I can do

int main()
{

//Create all my "best" selection algorithms
ABestTrack a_best_track;
BBestTrack b_best_track;
CBestCluster c_best_cluster;
DBestCluster d_best_cluster;

//Mix and match algorithms
MyAnalysis analysis_1( &a_best_track, &d_best_cluster );
MyAnalysis analysis_2( &b_best_track, &c_best_cluster );


  //In reality the rest of this would be in a loop
for ( something )
{
    const Event event;
    a_best_track.new_event( event);
    b_best_track.new_event( event);
    c_best_cluster.new_event( event);
    d_best_cluster.new_event( event);


    //Each analysis gets a reference to it's own definition of the "best" track
    analysis_1.DoAnalysis( event );
    analysis_2.DoAnalysis( event );

}
}
Was it helpful?

Solution

Pointers to internal members can be ok, I mean encapsulation is there to help you , not make your life harder. Piles of data don't need encapsulation as much as live objects do. When you have things that look/behave like data, it can be efficient to treat them that way. Thoughts:

  • Const pointers are better than not const. (not const really breaks encapulation)

  • Can you return value objects to be held by the interested parties, rather than ref/pointer?

  • Might your pointers be invalidated? eg by a re-allocation of the vector?

  • You could return a Event subclass, that essentially contains a index into the vectors, and that Event provides a decoding function for (this would help with encapsulation and pointer invalidation too)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top