我的问题类似于这些,但似乎并没有完全相关:
我得到的是这样的:
struct thingy;
struct container
{
static container& instance(); // singleton
int register_thingy(thingy*);
};
struct thingy
{
virtual ~thingy() {}
virtual int id() const = 0;
};
//template trick to force registration.
template < typename Derived >
struct registered_thingy : thingy
{
registered_thingy() : my_id(my_static_id) {}
int id() const { return my_id; }
private:
int my_id;
static int my_static_id;
}
template < typename Derived >
int registered_thingy<Derived>::my_static_id =
container::instance().register_thingy(new Derived);
Run Code Online (Sandbox Code Playgroud)
现在,concrete_thingy.cpp我在一个文件中:
struct my_concrete_thingy : registered_thingy<my_concrete_thingy>
{
my_concrete_thingy() {} // registered_thingy's constructor not called otherwise
};
Run Code Online (Sandbox Code Playgroud)
当然,上面的内容完全没用,但这里有抽象的真实行为.
当在作为整体编译的应用程序中使用时,这非常有效.现在的问题是,到目前为止,我无法使用这种技术,同时解决collection库中的行为问题.换句话说,我有一个thingys.lib文件包含concrete_thingy.cpp但是当链接到可执行文件时没有发生注册.在collection结束了现有的和工作正常,但它是空的.
现在,这是一个STATIC库,而不是DLL.这可能会稍微改变这个问题,而上述链接中所说的技术似乎并不适用.当然是关于函数的,我不知道如何将它应用于这些C++结构.
我尝试使用#pragma comment以下三行(当然是单独的)中的方法concrete_thingy.cpp,其中没有一个工作:
#pragma comment (linker, "/export:concrete_thingy")
#pragma comment (linker, "/export:concrete_thingy::my_static_id")
#pragma comment (linker, "/export:registered_thingy<concrete_thingy>::my_static_id")
Run Code Online (Sandbox Code Playgroud)
如果concrete_thingy.cpp在可执行文件而不是库中,一切正常.
那么,这是我的问题:
1)我可以做我想做的事情吗?我猜是的,但我只是不知道如何.
2)如果可能的话,我将如何获得MSVC++ 2010呢?
3)如果可能的话,我怎么能以便携的方式做到这一点?
简而言之,我要做的就是创建一个创建抽象实现的抽象工厂.它对这些实现一无所知,这些实现是使用全局初始化技巧注册的.这应该都在一个可以由应用程序链接的静态库中,这些实现应该可以通过该工厂获得.除了他们自己以外,没有人知道这些实现,因此正常的链接导致它们及其注册全局变量消失.
这不完全是我要做的,但它足够接近.
编辑:================================================ ====
看起来这种行为是"按设计".MS认识到无论是否使用它们都会发生造成副作用的物体的构造,它们使用标准中的漏洞,允许它们不包括任何使用的翻译单元:
https://connect.microsoft.com/feedback/viewfeedback.aspx?FeedbackID=244410&wa=wsignin1.0&siteid=210
/ OPT:NOREF选项在这种情况下显然没有做任何事情.
好吧,另一个回答好的尝试,但最终没有结果.我将使用改装技巧,但其余的似乎是一个红色的鲱鱼; 它是有道理的,因为有问题的模板实际上并没有在其他任何地方使用,所以它没有明确实例化的事实不应该有所作为...全局的声明仍然发生在A翻译单元中,它有副作用......我不认为标准允许它被优化掉.
关于标准的不幸,不说是否需要包括翻译单元是最终的问题.我认为C++ 0x正在对此做些什么,但也许不是......无论如何,MS根本不会包含单元,因为它不会将全局最终包含在可执行文件中,因此没有其他废话发生.
我决定做的,当然还有许多其他方法,就是创建一个文件'tag'变量.然后将该标签分配给可全局访问的功能(它可以分配或分配,或者参考被优化掉).然后必须从可执行文件中调用该函数.
我决定这样做,因为其余的仍然和以往一样.如果我只是编写一个手动注册类型的注册函数,我最终不会最终改变行为.另外,我可以通过这种方式做其他事情......我只需要确保任何可能属于这个fucktardery分类的东西都有一个标签并且可以访问该标签.
我将编写一堆辅助宏来使这个大多无痛.
| 归档时间: |
|
| 查看次数: |
5630 次 |
| 最近记录: |