众所周知c++缺少一个重要的机制,类成员静态初始化构造函数,如下例
class foo
{
private:
static int m_i =0; //这一句会报错
static const int m_j = 1; //ok
};
我们必需改成在cpp文件中加上 int foo::m_i =0;
现在问题来了,假如程序员A写了一个库,它用到了类静态成员,那么客户程序员需要在他的代码中对其进行初始化,但是如果有多个程序员都分别用到这个库,并且他们都共同完成同一个程序,会有什么样的问题呢?我想灾难是最好的形容。因此我想大部分的c++程序员希望有一个类似于C#中的静态成员初始化构造函数吧,如下
class foo
{
public:
static foo()
{...}
};
但目前c++标准好象并没有想法去支持它!我想了很久提出一种解决办法,大家看看如何
1) 利用函数体内的局部静态变量
2) 利用古老的宏
具体定义如下:#define STATIC_VAL(type,valname,initval) \
static type & static_m_##valname() \
{ \
static type m_##valname = initval; \
return m_##valname; \
}
#define STATIC_VAL_REF(valname) static_m_##valname()
class CTest
{
public:
CTest()
{
++ STATIC_VAL_REF(i);
} ~CTest()
{
-- STATIC_VAL_REF(i);
} int get_i()
{
return STATIC_VAL_REF(i);
} static void print()
{
printf("%s\n",STATIC_VAL_REF(msg));
}
private:
STATIC_VAL(int,i,0)
STATIC_VAL(const char*,msg,"this is")
};STATIC_VAL:完成静态变量的定义
STATIC_VAL_REF 取得静态变量的引用大家觉得这种方法有什么弊端么,另外我不是很清楚,如果在一个DLL中,函数体内的静态变量初使化是在什么时候。
class foo
{
private:
static int m_i =0; //这一句会报错
static const int m_j = 1; //ok
};
我们必需改成在cpp文件中加上 int foo::m_i =0;
现在问题来了,假如程序员A写了一个库,它用到了类静态成员,那么客户程序员需要在他的代码中对其进行初始化,但是如果有多个程序员都分别用到这个库,并且他们都共同完成同一个程序,会有什么样的问题呢?我想灾难是最好的形容。因此我想大部分的c++程序员希望有一个类似于C#中的静态成员初始化构造函数吧,如下
class foo
{
public:
static foo()
{...}
};
但目前c++标准好象并没有想法去支持它!我想了很久提出一种解决办法,大家看看如何
1) 利用函数体内的局部静态变量
2) 利用古老的宏
具体定义如下:#define STATIC_VAL(type,valname,initval) \
static type & static_m_##valname() \
{ \
static type m_##valname = initval; \
return m_##valname; \
}
#define STATIC_VAL_REF(valname) static_m_##valname()
class CTest
{
public:
CTest()
{
++ STATIC_VAL_REF(i);
} ~CTest()
{
-- STATIC_VAL_REF(i);
} int get_i()
{
return STATIC_VAL_REF(i);
} static void print()
{
printf("%s\n",STATIC_VAL_REF(msg));
}
private:
STATIC_VAL(int,i,0)
STATIC_VAL(const char*,msg,"this is")
};STATIC_VAL:完成静态变量的定义
STATIC_VAL_REF 取得静态变量的引用大家觉得这种方法有什么弊端么,另外我不是很清楚,如果在一个DLL中,函数体内的静态变量初使化是在什么时候。
解决方案 »
- 大家好呀,本人想做一个文字识别的软件,但在网上查找了很久都找不到一个词库,谁可为我提供一个,先谢谢了
- WinExec()要调用的参数有空格怎么办?
- install shield 11.5 如何判断操作系统
- 到了散分的时间(一周一次)
- 调用COM库出现问题,求救.
- vc程序如何在没装vc的机子上运行?
- VC一定要绑上MFC吗?后者好乱啊~~~~~
- 救命,我用CAsyncSocket做一个网络俄罗斯,老是丢失数据包
- 各位大神帮忙看一下为什么messagebox出来的是乱码
- tetgen四面体剖分
- 如何判断一个文件的编码格式 gb2312 gbk等
- 【江湖救急】wininet HttpSendRequest post 参数有中文?
可以将静态变量改成类实现cpp的匿名空间的全局变量.dll中的静态变量初始化在DllMain之前。
但是我不是很清楚象函数体内的静态变量初始化时机它是函数第一次运行时才进行呢,还是由CLR在调用main之前完成这里面区别很大,因为对于DLL就不存CLR的初始化了!!!
2、局部静态变量是非线程安全的,主要是指在初始化时有可能被线程切出去,从而导致多次初始化不清楚的是局部静态变量的析构发生在什么时候,由谁来调用析构
资料上是说程序结束时,
是main返回后,由clr来调用析构还是什么的,
在dll在又会是如何的呢?akirya 你说的类静态变量不要由用户来写初始化,那么我问你
你的类用于 dll中时,类静态成员初始化时机是在什么时候?
相关资料来自于《windows核心编程》--Jeffery Richter。
当使用VC来建立DLL时,C++运行时库提供启动和析构支持。首先DLL的真正入口并不是DllMain,,而是一个叫做_DllMainCRTStartup的函数。
1)当DLL文件映射至进程空间地址时,系统将调用这个函数,它初始化C/C++运行时库,并确保收到DLL_PROCESS_ATTACH通知时,创建任何全局或者静态c++对象(此时类的静态成员也会构建),然后调用DllMain,
2)当DLL收到DLL_PROCESS_DETACH,系统仍然调用此函数,它首先会调用DllMain,当DllMain返回后,对全局或静态对象进行析构。
3)对于Dll_THREAD_ATTACH和DLL_THREAD_DETACH而言,一般不做特别处理。
更详细的内容可以参考核心编程一书。的确,如上面各位所言,不管是EXE或是DLL不需要担心静态成员的初始化,看来是我多虑了,不管如何,我们要感谢c++的运行时,做了蛮多工作。
private:
static enum{ARRAY_NUM = 10};
}
算吗?