浅析C#与C++在静态构造函数上的异同

开发 后端
本文将对比的是C#与C++在静态构造函数上的异同,希望通过本文能让大家对C#与C++的不同点有所了解。

这里我们将讨论的是C#与C++在静态构造函数上的异同,通过这一关键点,希望能让大家更好的了解C#与C++,也对大家今后的工作有所帮助。

#T#

在C#中,类的静态构造函数用于在使用类之前进行相关的初始化工作;比如,初始化静态成员或执行特定操作。CLR 在***次创建该类对象或调用该类静态方法时自动调用静态构造函数。同时,CLR保证静态构造函数的线程安全性(准确地说是,只会调用一次,不存在多线程问题)。

下面是MSDN对静态构造函数特点的描述:

1.静态构造函数既没有访问修饰符,也没有参数

2.在创建***个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类

3.无法直接调用静态构造函数

4.在程序中,用户无法控制何时执行静态构造函数

C++语言规范并未包含类似静态构造函数的东西,但在使用类之前做初始化工作的需求却是客观存在的。就满足需求本身来讲,C++完全可以通过手动方式实现,但要处理好初始化时机,线程安全性等问题。本文则尝试通过C++的模版机制模拟实现静态构造函数,避免手动初始化的繁琐实现。对于需要静态构造函数的类A,只需用继承static_constructable<A>模版类,并提供 static void statici_constructor()静态方法即可:

  1. class A : static_constructable<A>  
  2. {  
  3. public:  
  4.     static void static_constructor() {  
  5.         std::cout << "static constructor a" << std::endl;  
  6.         s_string = "abc"//初始化静态数据  
  7.     }  
  8.  
  9.     static std::string s_string;  
  10.  
  11. public:  
  12.     A(){  
  13.         std::cout << "constructor a" << std::endl;  
  14.     }  
  15.  
  16. private:  
  17.     int m_i;  
  18. };  
  19.  
  20. std::string A::s_string;  
  21.  
  22. int _tmain(int argc, _TCHAR* argv[]){  
  23.     std::cout << "beginning of main" << std::endl;  
  24.  
  25.     assert(sizeof(A) == sizeof(int));//继承不改变A的内存布局  
  26.     assert(A::s_string == "");  
  27.     A a1;  
  28.     assert(A::s_string == "abc");  
  29.     A a2;  
  30.     std::cout << "end of main" << std::endl;  
  31.  
  32.     return 0;  

输出:

  1. beginning of main  
  2. static constructor a //创建A对象前自动调用静态构造方法,一次且仅一次  
  3. constructor a  
  4. constructor a  
  5. end of main 

下面是static_constructable类模板的实现:

  1. template<typename T>  
  2. class static_constructable  
  3. {  
  4. private:  
  5.     struct helper{  
  6.         helper(){  
  7.             T::static_constructor();  
  8.         }  
  9.     };  
  10.  
  11. protected:  
  12.     static_constructable(){  
  13.         static helper placeholder;      
  14.     }  
  15. };  

上面的实现把对A::static_constructor()的回调放到内部类helper的构造函数中;并在static_constructable<A>()中定义一个helper局部静态变量;C++保证在构造派生类 A的对象时,会先调用基类static_constructable<A>的构造函数,且静态局部变量只会构造一次,这样就达到调用一次且仅一次A::static_constructor()的目的。< /span>

static_constructor类模板简单地模拟了C#的静态构造函数机制,它具有以下特点:

1. 在***次构造类对象之前自动调用类提供的静态构造函数

2. 静态构造函数被调用的时机是确定的

3. 利用了C++的局部静态变量初始化机制保证了线程安全性(更正:实际并非线程安全,C++标准不涉及多线程问题,而一般编译器实现也非线程安全,更多参见评论部分)

4. 基于继承的实现机制并未改变派生类的对象内存布局

不过,和本文开始列出的C#静态构造函数的几个特点相比,本实现还有明显的不足:无法通过调用类A的静态方法触发静态构造函数;类A的静态构造函数必须是public的。希望有更好解决方案的朋友不吝赐教,也欢迎对此话题感兴趣的朋友交流探讨!

原文标题:C# vs C++之三:静态构造函数

链接:http://www.cnblogs.com/weidagang2046/archive/2009/11/14/1602463.html

责任编辑:彭凡 来源: 博客园
相关推荐

2011-06-11 21:36:44

C#C++

2011-06-14 12:27:38

C#C++

2009-07-31 15:44:02

C#静态构造函数

2009-08-13 17:30:30

C#构造函数

2009-08-13 18:02:11

C#静态构造函数

2010-01-27 17:16:52

C++构造函数

2009-08-14 09:15:28

C#调用构造函数

2009-08-13 17:38:42

C#构造函数

2009-08-13 18:10:31

C#静态构造函数

2009-07-31 15:37:45

C#静态构造函数

2009-08-20 14:28:00

C#静态构造函数

2009-08-13 18:15:06

C#继承构造函数

2009-08-14 09:43:59

C#复制构造函数

2009-09-18 09:02:45

CLR Via C#

2009-08-14 09:58:09

C#复制构造函数

2010-01-21 14:28:03

C++静态成员函数

2010-01-27 16:10:32

C++静态构造函数

2010-01-22 11:13:16

C++静态

2009-08-13 13:42:54

C#构造函数

2010-02-01 11:01:30

C++静态构造函数
点赞
收藏

51CTO技术栈公众号