error C2864:只有静态常量整型数据成员才可以在类中初始化

用visual Studio 2010不支持非静态常量整型数据成员在类内初始化,报错 error C2864:只有静态常量整型数据成员才可以在类中初始化



原因:

    VS2010支持C++11之前的标准(C++98/C++03),只有静态常量整型数据成员才可以在类中初始化。类定义只是一个框架,不是实例,不会分配存储空间,不会给它的成员变量赋值。只有类被实例化时,即创建对象,才会分配内存,才会给其成员变量赋值。静态常量整型数据成员是一个特例。


解决:

    1.可以通过构造函数实现类内非静态常量整型数据成员的初始化。

    2.C++11(VS2013版本及以后支持C++11)新标准规定,可以为数据成员提供一个类内初始值,创建对象时,类内初始值将用于初始化数据成员。没有初始值的成员将被默认初始化。

visual Studio 2015编译如下:


1)bookNo将被默认初始化为空字符串

2)units_sold与revenue将初始化为0,初始形式只有三种有效:

unsigned units_sold = 0;
unsigned units_sold = {0};
unsigned units_sold {0};

   此外,普通初始化还有第四种形式:
unsigned units_sold (0);  此圆括号形式对普通初始化有效,不可用于类内初始化

注:可用class替换struct实现类定义



<think>好的,我现在需要解决用户遇到的C++编译错误:OLED.C(1130) error C247 non-address constant initializer。用户还提到了引用中的错误信息,例如“non-const static data member must be initialized out of line”和“Initializer element is not a compile-time constant”。首先,我需要理解这些错误的原因,然后找到解决方法。 首先,错误C247的具体含义是什么?根据用户提供的引用,可能涉及到静态成员变量未正确初始化的问题。在C++中,非const的静态成员变量需要在外进行定义和初始化,而不能在内部直接初始化。例如: class MyClass { static int x; // 声明 }; int MyClass::x = 0; // 定义和初始化 如果在内直接给非const静态成员赋值,会导致错误,比如: class MyClass { static int x = 0; // 错误:non-const static数据成员必须在初始化 }; 这可能对应引用中的错误[^1]。另一个错误是关于初始化元素不是编译时常量,比如在全局或静态变量的初始化中使用了非常量表达式,如: int y = 10; int z = y; // 错误:y不是编译时常量 这会导致错误,如引用中的[^2]。现在用户遇到的C247错误,提到“non-address constant initializer”,可能是在初始化某个变量时使用了非常量表达式,特别是涉及地址的情况。例如,在C++中,静态成员的初始化如果是地址,可能需要是常量地址,或者使用constexpr。 接下来,用户的具体错误出现在OLED.C的第1130行,我需要考虑该行可能的代码结构。假设用户可能在中声明了一个静态成员变量,并尝试在内部初始化,或者尝试用非常量表达式初始化一个静态成员。例如: class OLED { static int* ptr = new int[10]; // 错误:非const静态成员不能初始化,且new不是常量表达式 }; 或者,在全局作用域中: int* globalPtr = new int[5]; // 如果这是静态存储期的变量,可能在某些上下文中导致错误,但通常允许,除非在特定限制下 或者,可能在结构体或中使用非编译时常量初始化静态成员: struct S { static const char* str = "Hello"; // 如果未在外定义,对于非整型静态成员需要constexpr或外定义 }; 另一个可能性是用户尝试用非常量地址初始化某个变量,比如在C++中,某些上下文要求初始化为地址常量,例如在数组大小或模板参数中,但这可能不直接相关。 可能的解决步骤: 1. 检查第1130行附近的代码,确认是否有静态成员变量在初始化。 2. 如果是非const静态成员,确保在外进行定义和初始化。 3. 如果初始化表达式涉及动态内存分配(如new),考虑改为在运行时初始化,或者在适当的位置(如构造函数)中进行。 4. 对于需要编译时常量的情况,使用constexpr或常量表达式。 例如,假设用户代码为: class OLED { static int* arr; }; int* OLED::arr = new int[10]; // 正确:在初始化静态成员 但如果用户尝试在初始化: class OLED { static int* arr = new int[10]; // 错误:非const静态成员不能在初始化 }; 此时需要将初始化移到外。另外,如果用户使用constexpr或const static,并初始化为编译时常量,可能可行: class OLED { static const int* const arr; // 需要外定义 }; const int* const OLED::arr = &some_constant_variable; 不过,这取决于具体使用场景。可能用户需要重新设计代码结构,避免在静态初始化中使用动态分配,或者改用单例模式等方式管理资源。 另外,错误C247可能特定于某些编译器(如旧版本的MSVC),其具体含义可能略有不同。需要查阅相关编译器文档。例如,MSDN可能指出C247是“非地址常量初始化器”,即初始化器必须是一个地址常量,比如在C++中,某些情况下初始化静态成员或全局变量时,要求地址是常量,例如指向某个固定地址的指针,或者使用constexpr修饰的指针。 例如,如果用户尝试: constexpr int* p = new int[5]; // 错误:new在constexpr中不允许 此时需要避免使用动态内存分配,或者改用静态存储期的数组: int myArray[5]; constexpr int* p = myArray; // 正确,如果myArray有静态存储期 因此,解决方案可能涉及将初始化移到外,使用常量表达式,或者调整变量的存储方式。 总结可能的解决方案: - 对于非const静态成员变量,在外定义并初始化。 - 确保初始化表达式是编译时常量,尤其是涉及地址时。 - 避免在静态初始化中使用动态内存分配,改用静态数组或提前分配。 现在需要将这些思路整理成用户友好的解答,并生成相关问题。</think>### 解决C++编译器错误C247: non-address constant initializer 当在C++代码中遇到错误`OLED.C(1130) error C247: non-address constant initializer`时,通常是因为在初始化静态成员变量或全局变量时,使用了**非编译时常量的地址表达式**。以下是具体原因和解决方法: --- #### 错误原因分析 1. **静态成员变量未正确初始化** 非`const`的静态成员变量必须在外单独初始化。若在内直接赋值,会触发似`non-const static data member must be initialized out of line`的错误。 2. **初始化表达式不是编译时常量** 在全局或静态变量的初始化中,如果使用了动态分配(如`new`)或运行时才能确定的值,会触发似`Initializer element is not a compile-time constant`的错误。 3. **地址常量不合法** 错误C247特别强调“非地址常量”,可能是尝试用动态生成的地址(如堆内存地址)初始化指针,而编译器要求此初始化必须是固定地址(如全局变量地址)。 --- #### 解决方法 ##### 1. 静态成员变量的初始化 若错误源于内的静态成员初始化,需将定义移到外: ```cpp // 错误示例(初始化非const静态成员) class OLED { static int* buffer = new int[100]; // ❌ 初始化非法 }; // 正确示例 class OLED { static int* buffer; // 内声明 }; int* OLED::buffer = new int[100]; // 外定义和初始化 ``` ##### 2. 使用编译时常量初始化 若变量需要编译时常量,改用`const`或`constexpr`: ```cpp // 错误示例(动态分配地址) constexpr int* ptr = new int[10]; // ❌ new不是编译时常量 // 正确示例(使用静态数组地址) int globalArray[10]; constexpr int* ptr = globalArray; // ✅ 全局数组地址是常量 ``` ##### 3. 避免动态初始化静态变量 如果无法使用常量初始化,改用懒加载或运行时初始化: ```cpp class OLED { static int* getBuffer() { static int* buffer = new int[100]; // 首次调用时初始化 return buffer; } }; ``` ##### 4. 检查全局变量的初始化 确保全局变量的初始化表达式是常量: ```cpp // 错误示例 int size = 100; int arr[size]; // ❌ size不是编译时常量(C++中数组大小需常量) // 正确示例 constexpr int size = 100; int arr[size]; // ✅ ``` --- #### 应用示例 假设错误出现在`OLED.C`的第1130行: ```cpp // 错误代码片段 class OLED { static char* fontData = (char*)0xA000; // 假设地址0xA000非法 }; ``` 修改为: ```cpp // 内声明 class OLED { static char* fontData; }; // 初始化 char* OLED::fontData = (char*)0xA000; // 需确保地址合法 ``` ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值