我正在做一个有一些“模块”的项目。 我在这里所说的模块是一个简单的类,它实现了特定的功能并派生自强制接口(interface)的抽象类 GenericModule。
future 应该会添加新模块。
一个模块的多个实例可以同时加载,也可以不加载,具体取决于配置文件。
我认为如果 future 的开发人员可以通过简单的一行将他的模块“注册”到系统中,那就太好了。或多或少与他们在 google test 中注册测试的方式相同。
我正在使用 visual studio 2005 构建项目。 代码完全在一个库中,除了 main() 是在一个 exec 项目中。 我想保持这种状态。
我从他们对 google test 所做的事情中找到了灵感。
我创建了一个模板化工厂。看起来或多或少像这样(我跳过了无趣的部分以使这个问题具有一定的可读性):
class CModuleFactory : boost::noncopyable
{
public:
virtual ~CModuleFactory() {};
virtual CModuleGenerique* operator()(
const boost::property_tree::ptree& rParametres ) const = 0;
};
template <class T>
class CModuleFactoryImpl : public CModuleFactory
{
public:
CModuleGenerique* operator()(
const boost::property_tree::ptree& rParametres ) const
{
return new T( rParametres );
}
};
和一个应该注册模块并将它的工厂添加到列表中的方法。
class CGenericModule
{
// ...
template <class T>
static int declareModule( const std::string& rstrModuleName )
{
// creation de la factory
CModuleFactoryImpl<T>* pFactory = new CModuleFactoryImpl<T>();
// adds the factory to a map of "id" => factory
CAcquisition::s_mapModuleFactory()[rstrModuleName ] = pFactory;
return 0;
}
};
现在在一个模块中,我需要做的就是声明一个模块:
static int initModule =
acquisition::CGenericModule::declareModule<acquisition::modules::CMyMod>(
"mod_name"
);
( 将来它会被包裹在一个允许做的宏中
DECLARE_MODULE( "mod_name", acquisition::modules::CMyMod );
)
好了,问题来了。
问题是,它确实有效,但并不是我想要的那样。
如果我将 initModule 的定义放在模块的 .cpp 中(我希望拥有它的地方)(甚至放在 .h 中),则不会调用 declareModule 方法。 如果我将静态 init 放在一个用过的 .cpp 文件中......它就可以工作。
使用我的意思是:在别处调用代码。
问题是 visual studio 在构建库时似乎丢弃了整个 obj。我想那是因为它没有在任何地方使用。
我激活了详细链接,在传递 n°2 中它列出了库中的 .objs 而模块的 .obj 不存在。
我找到了 this并尝试添加 /OPT:NOREF 选项,但没有成功。
我没有尝试将函数放在模块的 .h 中并从其他地方调用它,因为关键在于能够在文件的一行中声明它。
另外我认为问题类似于this one但解决方案是针对 g++ 而不是视觉的 :'(
编辑:我刚刚阅读了这个问题的答案中的注释。好吧,如果我从另一个 .cpp #include 模块的 .h,并将 init 放在模块的 .h 中。它有效并且初始化实际上完成了两次......每个编译单元一次?好吧,它似乎发生在模块的编译单元中......
如果您不同意我正在尝试做的事情,请尽管说出来,但我仍然对解决方案感兴趣
最佳答案
如果你想在你的“模块”中使用这种自注册行为,你假设链接器正在优化 initModule 因为它没有被直接引用可能是不正确的(尽管它也可能是正确的:-)。
当您注册这些模块时,您是在修改另一个在文件范围内定义的静态变量吗?如果是这样,您至少有一个初始化顺序问题。这甚至可能只在发布版本中表现出来(初始化顺序可能因编译器设置而异),这可能会让您相信链接器正在优化这个 initModule 变量,即使它可能没有这样做。
如果您想以这种方式做事,那么模块注册类型的变量(无论是注册者列表还是其他什么)应该是惰性构造的。示例:
static vector<string> unsafe_static; // bad
vector<string>& safe_static()
{
static vector<string> f;
return f;
} // ok
注意上面的并发问题。调用 safe_static 的多个线程需要一些线程同步。
我怀疑您真正的问题与初始化顺序有关,尽管链接器似乎排除了 initModule 定义。通常,链接器不会省略具有副作用的引用。
如果您发现这不是初始化顺序问题并且链接器省略了代码,那么强制它的一种方法是导出 initModule(例如:MSVC 上的 dllexport)。您应该仔细考虑这种自注册行为是否真的比添加到函数调用列表以初始化“模块”的简单过程更重要。如果每个“模块”都在单独的共享库/DLL 中定义,您也可以更自然地实现这一点,在这种情况下,您的宏可以只定义要导出的函数,该函数可以由主机应用程序自动添加。当然,这带来了必须为您创建的每个“模块”定义一个单独项目的负担,而不是仅仅向现有项目添加一个自注册的 cpp 文件。
关于c++ - 静态初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3104923/
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“