C++ 插件的初始化器问题。测验

C++ 插件的初始化器问题。测验,c++,initialization,C++,Initialization,我有一个更长更复杂的问题,有这个代码 不过我会简化它。下面的代码有什么问题吗?有没有更好的方法来执行下面的操作 我担心这一行std::list&plugins,以及如何设置它,同时保持它的引用。但我会让你们把代码分开 #include <list> #include <string> class Plugin{ public: static std::list<Plugin*>*plugins; std::string name; Pl

我有一个更长更复杂的问题,有这个代码

不过我会简化它。下面的代码有什么问题吗?有没有更好的方法来执行下面的操作

我担心这一行
std::list&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;
#包括
#包括
类插件{
公众:
静态标准::列表*插件;
std::字符串名;
插件(const std::string&n):名称(n)
{
静态std::列出插件;
这->插件=&plugins;
插件。推回(这个);
}
};
//main.cpp
#包括“plugin.h”
类Plugin1:公共插件{
公众:
Plugin1():Plugin(“1”){}
};
静态插件1插件;
std::list*Plugin::plugins;
std::list&plugins=*Plugin::plugins//全局名称plz
int main(){
for(auto c=plugins.cbegin();c!=plugins.cend();++c){
printf(“%s\n”,(*c)->name.c_str());
}
}
//PluginA.cpp
#包括“plugin.h”
类PluginA:公共插件{
公众:
PluginA():PluginA(“A”){}
};
静态插件;
我觉得这很奇怪。 如果您的目标是拥有某种全局插件容器/管理器,那么有没有理由不使用这样的单例模式:

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;
};
类插件容器{
静态插件容器和实例()
{ 
静态插头容器*m_this=0;
如果(!m_this)
m_this=新的插头容器;
返回*m_this;
}
无效寄存器(Plugin*Plugin){…添加到列表…}
const list&plugins()const{…返回它…}
受保护的:
PluginContainer(){}
};
类插件{
公众:
插件(const std::string&n):名称(n)
{
PluginContainer::instance().register(此);
}
私人:
std::字符串名;
};

我修改了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
Plugin(const std::string&n):name(n){static std::list plugins;this->plugins=&plugins;if(n.length()==0)return;plugins.push_back(this);}
静态std::list*ForceInit(){Plugin d(“”);返回plugins;}
std::list&plugins=*Plugin::ForceInit()//全局名称plz

我不明白,为什么要使用函数的静态变量作为静态成员指针的目标。为什么不将成员插件声明为静态std::list插件;像往常一样工作吗?@没人:我学到了一个教训,那就是我必须重载新的变量,原因是所有变量都是无序初始化的。然而,如果你用一个静态变量调用一个函数,它肯定会被初始化,这就是我这么做的原因。否则,我只能希望在插件之前初始化静态成员变量,或者找到另一种方法来保证它。@acidzombie24:如果您调用的“函数”是一个也被静态调用的构造(作为静态变量的构造函数),那么这就不起作用了。所有静态初始化都首先发生,但是静态初始化的顺序和非静态全局初始化一样是未知的。这属于打开状态,所以如果我理解正确的话,为了方便起见,您需要全局名称插件?如果是这样,那么您可以声明std::list插件;全局地使用引用作为静态成员,或者不全局地定义引用并使用名称空间插件;我会帮助你的。但我不喜欢两种方法,我不喜欢这个解决方案。这比我的代码更糟糕。我的代码唯一真正的问题是我无法访问具有全局范围的
插件,这并不能解决这个问题。为了安全起见,您最好每次都使用plugin::plugins()。您使用单音键使情况变得更糟可能您的代码背后有一些我不明白的原因,但是
list&plugins=PluginContainer::instance.plugins()
如何解决您的问题呢?别误会我,我只是想知道你为什么要那样做。仅仅获得一个插件的全局列表就显得过于复杂了。我想可以。因为您在该行上强制初始化。我知道我只使用一个实例,但我宁愿不使用单例,因为它只强制使用一个实例。如果我更改它,它会打断使用
::instance()