Virtual Classes
Jul 11, 2011 at 3:58am UTC
I'm somewhat new to the concept. It's a feature of C++ I've been avoiding for a _long_ time for reasons less than good (other than the constant vtable overhead slander). I wanted to use pure virtual classes to hold a plugin interface. However, I'm rather confused as to how to make a decent plugin. Observe the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#include <iostream>
#include <list>
#include <memory>
struct IPlugin
{
virtual void plugin_func() =0;
virtual void plug_func() =0;
};
struct Plugin : public IPlugin
{
virtual void plugin_func() { std::cout << "101" << std::endl; }
virtual void plug_func() { std::cout << "test" << std::endl; }
};
struct AnotPlugin : public IPlugin
{
virtual void plugin_func() { std::cout << "LoL" << std::endl; }
virtual void plug_func() { std::cout << "blahahblah" << std::endl; }
};
struct PluginHolder
{
template <class PluginClass>
void register_plugin()
{
plugList.push_back(std::shared_ptr<IPlugin>(new PluginClass));
}
void plugin_func()
{
for (auto iter = plugList.begin(); iter != plugList.end(); ++iter)
{
(*iter)->plugin_func();
}
}
void plug_func()
{
for (auto iter = plugList.begin(); iter != plugList.end(); ++iter)
{
(*iter)->plug_func();
}
}
std::list<std::shared_ptr<IPlugin> > plugList;
};
int main(void )
{
PluginHolder ph;
ph.register_plugin<Plugin>();
ph.register_plugin<AnotPlugin>();
ph.plugin_func();
ph.plug_func();
}
There are some problems with this obviously. I was also rather confused as to the benefits of a factory over something like this as I was told it would be most beneficial (nor do I see how it would work for a plugin system). Am I taking a wrong approach? Could I get advice on how to go about this?
EDIT: Sorry for the poor example. It was meant to be basic. Also, to compile, it requires a C++11 capable compiler. Should compile with VC++, GCC (with --std=gnu++0x), clang.
Last edited on Jul 11, 2011 at 4:02am UTC
Jul 11, 2011 at 7:08am UTC
Hi,
Your solution works at compiled time as well. If you want to use it at run time you can change it as the following:
1 2 3 4 5 6 7
void register_plugin(IPlugin * ipn) //at run time
{
plugList.push_back(std::shared_ptr<IPlugin>(ipn));
}
...
ph.register_plugin(new Plugin);
So the whole code goes like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
#include <iostream>
#include <list>
#include <memory>
#include <tr1/memory>
using namespace std::tr1;
struct IPlugin
{
virtual void plugin_func() =0;
virtual void plug_func() =0;
};
struct Plugin : public IPlugin
{
virtual void plugin_func() { std::cout << "101" << std::endl; }
virtual void plug_func() { std::cout << "test" << std::endl; }
};
struct AnotPlugin : public IPlugin
{
virtual void plugin_func() { std::cout << "LoL" << std::endl; }
virtual void plug_func() { std::cout << "blahahblah" << std::endl; }
};
struct PluginHolder
{
template <class PluginClass>
void register_plugin() // at compiled time
{
plugList.push_back(std::shared_ptr<IPlugin>(new PluginClass));
}
void register_plugin(IPlugin * ipn) //at run time
{
plugList.push_back(std::shared_ptr<IPlugin>(ipn));
}
void plugin_func()
{
for (auto iter = plugList.begin(); iter != plugList.end(); ++iter)
{
(*iter)->plugin_func();
}
}
void plug_func()
{
for (auto iter = plugList.begin(); iter != plugList.end(); ++iter)
{
(*iter)->plug_func();
}
}
std::list<std::shared_ptr<IPlugin> > plugList;
};
int main(void )
{
PluginHolder ph;
ph.register_plugin<Plugin>();
ph.register_plugin<AnotPlugin>();
ph.register_plugin(new Plugin);
ph.plugin_func();
ph.plug_func();
}
Topic archived. No new replies allowed.