I'm looking to write a small bit of C++11 re-usable code to provide similar functionality seen in COM/ATL's IUnknown. Specifically, I'm interested in the QueryInterface() functionality.
A have a few requirements in mind:
- Do not rely on RTTI. This rules out dynamic_cast<> (this is not out of personal choice!)
- Remove possible coding mistakes by making use of std::shared_ptr<> instead of raw pointers. Shared ptr also provides useful in-built functionality like custom deleters.
- Use enum ids to refer to interfaces.
- Cross platform is a must.
Some code provided by Alexandre in another SO question has given me some ideas. Nonetheless, what I am keen to try achieve is return a std::shared_ptr object from the query interface method.
I have started to write some code (see below) to demonstrate what I'm trying to achieve. I appreciate that it is not complete.
Trying to flesh this out, I quick ran into all sorts of problems related to type-casting. The code soon felt 'hackish'.
#include <iostream>
#include <memory>
#include <map>
//////////////////////////////////////////////////////////////////////
enum iid
{
IID_ANONYMOUS = 0,
IID_FOO = 1,
IID_BAR = 2,
};
//////////////////////////////////////////////////////////////////////
class abstract_anonymous
{
public:
virtual ~abstract_anonymous() {}
// Return 0 if succesful.
template <class INTERFACE>
bool query_interface(const iid id,
std::shared_ptr<INTERFACE> &inout_apObj)
{
// Magic here.
}
protected:
virtual std::map<iid, zzzzzzzzzz > &interfaces_map() const = 0;
};
//////////////////////////////////////////////////////////////////////
class anonymous_base_impl // : public std::enable_shared_from_this<abstract_anonymous>
{
public:
anonymous_base_impl()
{
add_interface(IID_ANONYMOUS, xxxxxxxxxxxx );
}
~anonymous_base_impl() = default;
protected:
void add_interface(const iid id, yyyyyyyyyyy )
{
m_mapInterfacs.emplace({id, yyyyyyyyyyy});
}
std::map<iid, zzzzzzzzzz > &interfaces_map() const override
{
return m_mapInterfacs;
};
private:
std::map<iid, zzzzzzzzzz > m_mapInterfacs;
};
Any tips/suggestion would be much appreciated.
Aucun commentaire:
Enregistrer un commentaire