gpt4 book ai didi

c++ - 静态成员的两个实例,怎么可能?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:32:10 24 4
gpt4 key购买 nike

我有一个多线程应用程序。我在共享库中声明了一个带有静态成员的类。

从不同库的不同线程打印成员的地址显示不同的结果。

//声明

template <class OBJECT>
struct Container
{
static int m_member;
};

template <class OBJECT>
int Container<OBJECT>::m_member;

//打印

cout << (void*) &Container<int>::m_member << endl;

怎么可能呢?

最佳答案

如果您有不同的库(我猜是不同的动态库),那么您可能会有一些重复的代码和静态变量。

具体细节取决于您使用的特定动态库技术。我想说的是,例如,在 Windows DLL 中您将有重复的代码和变量,但在 Linux SO 中您不会。

无论如何,您应该提供有关操作系统和项目布局的更多详细信息。

更新:啊,但是你的类(class)是一个模板!共享库中的模板实例化是一个奇怪的野兽!为了确保在所有过程中只使用您的类的一个拷贝,您必须显式实例化模板并确保在 SO 中导出此实例化,并从客户端代码中使用它。细节因编译器而异,但您可以检查 std::string 是如何完成的,例如:

在头文件中:

namespace std
{
extern template class basic_string<wchar_t>;
}

在库的源代码中:

namespace std
{
template class basic_string<wchar_t>;
}

当然,您需要提前知道您的模板需要哪些实例化。显然,SO 无法导出使用它一无所知的类型的实例化。

更新:啊,但是你有两个不同的库来实例化模板...那么如果两个库都将显式实例化定义为 extern 共享的 ELF 魔法应该合并两者实例化为一体。

又一更新:使用模板和共享对象后,它通常就可以正常工作了。我现在的猜测是您正在使用 -fvisibility=hidden 或类似的方式编译库。如果是这种情况,只需编写:

template <class OBJECT>
struct __attribute__((visibility("default"))) Container
{
static int m_member;
};

使模板特化进入动态符号表,从而避免重复。

关于c++ - 静态成员的两个实例,怎么可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11666166/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com