Reputation: 465
I'm trying design a set a classes to store / access / analyse my data but I'm not sure how they should fit together.
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.
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?
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 );
}
}
Upvotes: 1
Views: 196
Reputation: 2988
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)
Upvotes: 1