类内const static(static const)成员变量初始化问题

本文详细探讨了C++类中conststatic成员变量的初始化问题,包括不同编译器环境下允许的初始化位置及原因。通过实例代码对比,解释了解释一和解释二的不同观点,并通过实际测试验证了各自的正确性。

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

  在查找const相关资料的过程中,又遇到了另外一个问题,就是C++类中const static(或者static const)成员变量应当如何初始化的问题。

  查阅了许多资料,发现VC环境下,只允许const static成员变量在类外初始化,这个应该是编译器遗留下的bug(你也可以说是要求严格)。

  在其他编译器下,整型以及枚举类型的const static成员变量是允许在声明的同时进行初始的,其中整型包括int、short、long、char等,非整型是指浮点型 包括float、double等。尽管可以在类内进行初始化,但是我在网上看到两种解释:

解释一

  虽然可以进行初始化,但是这种初始化时不够严格地,倘若对变量取地址 (这里并不是指 &操作符,而是指所有需要用到这个变量的存储空间的操作 比如 ++ 之类,其实这儿我也没看懂到底什么是取地址),就会出现错误,这是因为这种在类内的初始化是不会分配内存的,应当再次在类外进行定义来获取内存分配(无需再赋值)。

class people{

public:

    const static int age = 18;

};

const int people::age;

解释二

  之所以整型有这种特权,是为了设计一个更明确(类型)的常量定义语法来取代用enum定义常量的旧方式。因为出发点是这个,所以才仅仅只是对静态整形常量特殊处理,因为enum也只能是整型值。现在的最新标准完全允许在类内进行定义,并且当你用到取地址操作时,它就会分配内存,类似于常量折叠(const folding),所以无需在外再次定义,这是完全没有问题的。

class people{

public:

    const static int age = 18;

};

//不需要const int people::age;

  

  对于上述解释,作为一个初学者,也没法从绝对的知识点上判断到底哪个是对的,根据我在VS2013中敲代码实际测试来看,解释一、二是代码都是对的,都不会报错,但是我在codeblock中运行时,如果对age进行const int *p=&people::age操作时,一不会报错而二报错,所以我支持解释一的说法。如果有哪位大神有幸看到这篇文章,还望指点一二,感激不尽!

转载于:https://www.cnblogs.com/yanqi0124/p/3795244.html

### 如何使用 `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、付费专栏及课程。

余额充值