vc++对类内const static int变量初始化后的处理

本文探讨了在Visual Studio 2008中对于类内初始化const static int成员变量时出现的连接错误问题。通过实验发现,虽然标准允许在类内初始化这类变量,但在某些情况下VS2008会出现重复定义的错误。文章提供了测试代码,并讨论了不同编译器的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天论坛里有人发帖http://topic.youkuaiyun.com/u/20081110/21/58b849c2-efcd-473e-a59f-9e783223a15c.html提出相关问题。

发现,在类内初始化了const static int变量后,总是出现连接错误。后经测试后果然是,但并不总是。但这样显然是跟标准不符的,标准说对于const static int是可以在类内初始化的,但还是需要在类外定义。

 

现把存疑记录在此。

 

的确是个很奇怪的问题。

1、int型的const static 成员可以不必类外定义?或许吧,试过几个编译器的确如此。
2、但标准是说需要类外定义的呀。用编译器测试,当类定义、调用程序都在一个文件中时,类外定义const static成员都顺利通过了(gcc vs2008)
3、但进一步看,分开类定义和调用程序成两个文件时,问题来了。gcc顺利通过。vs2008出现重复定义,连接出错。这时候无论你把类外定义语句放到哪个文件,vs都通不过。(当多个文件include类声明,只要有文件在类外定义了变量,所有的include了头文件的其他cpp都会出连接错)

这样看起来,vs是把这种类内的const static int变量自动定义和分配了空间。但奇怪在,当只有一个文件include类声明时,又是可以类外定义的。不知道是不是属于vs的bug。(至少是跟标准不符吧)

 

后来在其他论坛也查到类似问题http://www.megasolutions.net/cplus/Is-this-a-bug-of-the-C++-compiler-of-VS-2005_-77566.aspx?hide_quotes=no

 也是怀疑是否是vc++的bug。
  1. See an example at first: 
  2. hdr.h 
  3. -------------- 
  4. struct X 
  5.         static const int m = 9; 
  6. }; 
  7. ===================== 
  8. source1.cpp 
  9. --------------- 
  10. #include "hdr.h" 
  11. const int X::m; 
  12. ===================== 
  13. main.cpp 
  14. --------------- 
  15. #include "hdr.h" 
  16. int main() 
  17. {} 
  18. ===================== 
### 如何使用 `const` 修饰符初始化的成员变量 #### C++ 在C++中,当声明一个成员变量为`const`时,该成员变量必须在其定义处或通过构造函数的初始化列表来赋初值。一旦被赋予初始值,则不能再改变其值。 对于非静态成员,在构造函数中利用初始化列表完成这一操作是最常见的做法[^1]: ```cpp class CExample { public: CExample() : m_a(1), m_b(2) {} private: const int m_a; int m_b; }; ``` 而对于整型静态常量数据成员而言,可以直接于体内指定默认值,这得益于这成员具有编译时常量性质的特点[^2]: ```cpp class ExampleWithStaticConstMember { public: static constexpr int s_value = 42; // 静态常量成员可以在此直接初始化 }; ``` 另外,自C++11起引入了更灵活的方式——允许直接在定义里给非静态成员设定初始值;不过需要注意的是,如果同时存在显式的初始化器(即初始化列表),那么后者会覆盖前者[^3]: ```cpp class Human { private: const std::string bloodType = "A"; // 初始化 }; ``` #### C# 相比之下,C#处理`const`字段的方式略有不同。在C#里面,`const`关键字用来创建真正的编译期常数,这意味着它的值不仅限定了不能更改,而且实际上是在程序运行前就已经确定下来并嵌入到最终生成的IL代码中的。因此,所有的`const`字段都必须立即给出具体的数值表达式作为其值,并且这个表达式应该能够完全由编译器计算得出结果。 下面是一个简单的例子展示如何在C#中定义和使用`const`: ```csharp public class Person { public const string BloodType = "O"; } ``` 值得注意的是,在C#中不存在像C++那样的初始化列表机制,所以任何需要动态决定的只读(`readonly`)而非真正意义上的常量(`const`)属性应当采用其他方式实现,比如通过构造函数参数传递并在实例化对象的时候设置相应的私有字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值