首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么在头文件中声明“静态const”成员会导致链接器错误?

为什么在头文件中声明“静态const”成员会导致链接器错误?
EN

Stack Overflow用户
提问于 2011-03-03 16:42:18
回答 5查看 4.4K关注 0票数 6

我有一个类声明(.h文件),如下所示:

代码语言:javascript
复制
struct MyClass {
    static const uint32_t SIZE = sizeof(MyType);
};

当将我的程序链接到一起时,我会得到MyClass::SIZE的链接器错误。nm确认符号未定义。http://forums.devshed.com/c-programming-42/linker-errors-undefined-reference-to-static-member-data-193010.html似乎解决了我的问题,指出“类静态对象也必须像普通全局一样在任何函数或类之外声明”。

我有两个问题:

  1. 这个解释对我的情况有效吗?如果是这样的话,你能更详细地解释一下为什么这是真的吗?
  2. ,什么是最好的解决方法?我希望将这个成员的初始化完全保存在.h文件.

中。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-03 17:35:58

您的问题可能与使用您变量地址的人无关。它可能只是编译器选择不使用变量作为常量表达式,即使它可以。例如:

代码语言:javascript
复制
f(int const&);
struct X { enum { enum_val = 42 }; static int const static_mem = 42; };

f(5);
f(X::enum_val);
f(X::static_mem);

在前两种情况下,编译器需要将输入作为常量表达式使用,并且可以使用此表达式初始化const&。然而,最后一种情况则不同。尽管您的意图可能是使用static_mem作为常量表达式,并且这样做完全合法,但编译器可以自由地进行其他操作,而且有些编译器实际上会创建对变量本身的引用。这是变量的“使用”,因此需要在程序中的某个地方定义该变量。

有两种方法可以解决这个问题:

1)向程序中添加定义。

2)改用枚举:结构X{ enum { static_mem =?};};

第一个解决方案是必要的,如果您有意愿,采取您的变量的地址是可能的。不过,很有可能你没有,或者你已经创建了这个定义。后一种解决方案迫使编译器使用X::static_mem作为常量表达式,因为枚举成员实际上并不作为程序中的对象存在。基于你在问题中最后的陈述,我打赌这是你真正想要的解决方案。

票数 5
EN

Stack Overflow用户

发布于 2011-03-03 16:50:10

只有当静态成员积分常数的地址被接受时,标准才需要为其定义一个静态成员积分常量,否则带有初始化器的声明就足够了。链接器错误消息应该提到哪个对象/函数采用MyClass::SIZE的地址。

票数 2
EN

Stack Overflow用户

发布于 2011-03-03 16:48:25

如果你要这么做

代码语言:javascript
复制
//.h file
struct MyClass 
{
    static const uint32_t SIZE = sizeof(MyType); //this is declaration!

}; 

//.cpp file
const uint32_t MyClass::SIZE; //this is definition - necessary!
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5183703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档