So, I was wondering how to create some kind of a code audit in C++ using a tracking mechanism of sorts.
Consider the following classes, where two separate mirrors, A and B, provide messages to a listener.
class MirrorA
{
void one(int a) { m_mirrrorListener.three(a); }
};
class MirrorB
{
void two(int b) { m_mirrrorListener.three(b); }
};
class MirrorListener
{
void three(int c) { std::cout << c << std::endl; }
};
Now, let's say that, for some reason, three needs to know if it was triggered by one() or two().
We can pass along a value like so:
enum mirrorSource_t
{
FROM_ONE = 1,
FROM_TWO = 2
}
class MirrorA
{
void one(int a) { m_mirrrorListener.three(a, FROM_ONE); }
};
class MirrorB
{
void two(int b) { m_mirrrorListener.three(b, FROM_TWO); }
};
class MirrorListener
{
void three(int c, mirrorSource_t source) { std::cout << c << " From " << source << std::endl; }
};
But then we have to update the signature of three and its invocation whenever it needs new information.
So, what if we had a singleton message tracker (referenced as m_mirrorMessageTracker in other classes) that could track an arbitrary number of messages?
enum mirrorSource_t
{
FROM_ONE = 1,
FROM_TWO = 2
}
class MirrorMessage
{
public:
MirrorMessage(mirrrorSource_t t) : source(t) {}
get() { return source; }
private:
mirrorSource_t source;
};
class MirrorMessageTracker {
public:
MirrorMessage& MirrorMessageTracker::trackEvent(mirrorSource_t value)
{
trackedMessages.push_back(MirrorMessage(value));
return trackedMessages.back();
}
MirrorMessage& MirrorMesssageTracker::getCurrentEvent()
{
return trackedMessages.back();
}
static MirrorMessageTracker& getInstance()
{
if(!m_Tracker)
{
m_pTracker = new MirrorMessageTracker();
}
return *m_pTracker;
}
private:
MirrorMessageTracker() { }; //
static MirrorMessageTracker* m_pTracker;
std::vector<MirrorMessage> trackedMessages; // assumption is that tracked messages are
// single-threaded and unwind in a LIFO manner.
};
class MirrorA
{
void one(int a)
{
MirrorMessage createdMessage = m_MirrorMessageTracker.trackMessage(FROM_ONE);
m_mirrrorListener.three(a);
}
};
class MirrorB
{
void two(int b)
{
MirrorMessage createdMessage = m_MirrorMessageTracker.trackMessage(FROM_TWO);
m_mirrrorListener.three(b);
}
};
class MirrorListener
{
void three(int c)
{
MirrorMessage& message = m_MirrorMessageTracker.getCurrentMessage();
if (message.get() == FROM_ONE)
{
std::cout << c << std::endl;
}
else if (message.get() == FROM_TWO)
{
std::cout << c << c << std::endl;
}
else
{
std::cout << c << c << c << std::endl;
}
}
};
I would like for the tracked message to be removed from the tracker after createdMessage goes out of scope in one and two. Can this be done with a particular type of boost smart pointer? Something like:
std::vector<boost::shared_ptr<MirrorMessage> > trackedMessages;
vector::push_back would create a copy of the message and place it into the vector so I'm not sure if it's possible with a shared pointer, though.
The more common pattern to create singletons actually is
Also you should consider to forbid copying and assignment for your
MirrorMessageTracker
class, by making these operationsprivate
: