我有一个更复杂的问题并且有这段代码http://www.ideone.com/VEOvp
但是我会简化它。下面的代码是否有任何问题,是否有更好的方法来执行以下操作?
我担心这一行std::list<Plugin*>& plugins
以及如何在保持参考的同时设置它。但我会让你们分开选择代码。
#include <list>
#include <string>
class Plugin{
public:
static std::list<Plugin*>*plugins;
std::string name;
Plugin(const std::string&n) : name(n)
{
static std::list<Plugin*> plugins;
this->plugins=&plugins;
plugins.push_back(this);
}
};
//main.cpp
#include "plugin.h"
class Plugin1 : public Plugin{
public:
Plugin1():Plugin("1"){}
};
static Plugin1 plugin;
std::list<Plugin*>* Plugin::plugins;
std::list<Plugin*>& plugins = *Plugin::plugins; //global name plz
int main(){
for(auto c=plugins.cbegin(); c!=plugins.cend(); ++c) {
printf("%s\n", (*c)->name.c_str());
}
}
//PluginA.cpp
#include "plugin.h"
class PluginA : public Plugin{
public:
PluginA():Plugin("A"){}
};
static PluginA plugin;
答案 0 :(得分:1)
这对我来说很奇怪。 如果您的目标是拥有某种全局插件容器/管理器,那么有任何理由不使用这样的单例模式:
class PluginContainer {
static PluginContainer& instance()
{
static PluginContainer* m_this = 0;
if(!m_this)
m_this = new PluginContainer;
return *m_this;
}
void register(Plugin* plugin) { ... add to a list ... }
const list<Plugin*>& plugins() const { ... return it ... }
protected:
PluginContainer() {}
};
class Plugin{
public:
Plugin(const std::string& n) : name(n)
{
PluginContainer::instance().register( this );
}
private:
std::string name;
};
答案 1 :(得分:0)
我修改了2行并添加了ForceInit。它应该是安全但未经证实的。
Plugin(const std::string&n) : name(n){ static std::list<Plugin*> plugins; this->plugins=&plugins; if(n.length()==0) return; plugins.push_back(this); }
static std::list<Plugin*>* ForceInit() { Plugin d(""); return plugins; }
std::list<Plugin*>& plugins = *Plugin::ForceInit(); //global name plz