C++-c++模板类静态成员的初始化问题

发布于 2016-10-21 17:32:08 字数 1340 浏览 1324 评论 1

之前在开发时发现一个模板类静态成员初始化的问题,现在整理一下贴出来,一起讨论一下。windows下的动态链接库有入口函数,可以进行初始化和收尾工作,linux下没有。动态链接库被多个进程共享,显示的调用略显麻烦,查了一下资料,可以利用全局对象的构造和析构函数来实现这个目的,但是自己尝试时发现并不绝对有效。问题的原因和动态链接库无关,原始代码简化如下,

#include <iostream>
#include <list>
using namespace std;

class MyList: list<void*>
{
public:
MyList()
{
cout << "class MyList init" << endl;
}
};

template<class _T>
class Trash
{
public:
static MyList m_trash;
public:
Trash()
{
cout << "class Trash init" << endl;
}

static void Init()
{
cout << "Trash init data" << endl;
m_trash.push_back(NULL); //报错代码
}
static MyList& GetTrash() { return m_trash; }
};

template<class _T>
MyList Trash<_T>::m_trash;

class Conf
{
public:
Conf()
{
cout << "class Conf Init" << endl;
Trash<void*>::Init();
}

~Conf()
{
cout << "class Conf Del" << endl;
}
};

static Conf g_conf; //通过这个对象的构造和析构实现动态链接库的自动初始化和释放

///////////////////////

int main(int argc, char* argv[])
{
return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜柠檬 2017-03-29 03:44:58

1: 第一个疑问,请将MyList的继承改为public属性
2: 不是初始化问题,而是cpp的特性,第一次使用的时候初始化,否则没有必要进行初始化
3: m_trash.push_back(NULL);报错的原因,这里还不能调用基类的方法,类型还没构造完成

你的原始代码编译结果:
http://ideone.com/rtBmV

1: 继承方式修改为public编译执行结果,出现错误,是在m_trash.push_back(NULL);发生的错误
http://ideone.com/57gpc

2:屏蔽m_trash.push_back(NULL);
http://ideone.com/SYqTJ
输出结果为:
class Conf Init
Trash init data
class Conf Del
由于屏蔽了m_trash的相关操作,所以m_trash并没有初始化。

3:在MyList中增加一个f方法,并在Init中进行调用,编译执行结果:
http://ideone.com/Lk2lf
输出结果:
class Conf Init
Trash init data
in MyList::f() // f方法内的输出
class MyList init
class Conf Del

4:如果按照你所说的,将Trash的模版属性去掉
http://ideone.com/3DRe5
输出结果:
class MyList init
class Conf Init
Trash init data
class Conf Del

3和4一个含有模板类的静态成员,一个是普通类的静态成员,输出没有什么大差异,对于类模版的静态成员,并不是类模版这个类型级别的,而是类模版实例的某一个具体类型级别的数据,也就是说Trash<void>会有一个m_trash成员,Trash<int> 会有一个m_trash成员,当没有一个具体的类型时,它只能是一个符号标志,不会进行初始化,除非你实做了一个类型出来,比如3中实做了一个Trash<void*>,那么相应的有MyList的初始化操作。而4中,这个类型已经确定了。这里只要能保证在第一次使用之前对其进行初始化就可以,没有规则要求必须是在什么时机。

5:你说的“类的静态成员竟然是在创建第二个对象时才初始化的”,不明白你的意思,没有看到这种情况。“在Init里添加代码m_trash,结果没变,自己用自己还不算”,没有遇到这种情况。
“linux下聪明着呢,windows傻了”,似乎也没有吧。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文