static - 为什么跨不同源文件的多个变量定义是一个问题,但跨不同源的多个类定义不是
问题描述
我目前正在 uni 学习 C++(更准确地说是 C++03),并且遇到了静态成员的初始化。非常量静态成员应在类内部声明,但在外部定义。此外,它们也应该在源文件中声明,而不是在头文件中。据我了解,这是因为如果您有一个myClass.h头文件,其中包含一个myClass类,并且A.cpp和B.cpp包含它,那么您可以保护自己免受同一个源文件中的多个定义的影响包括警卫,但您无法防止myClass.h在A.cpp和B.cpp中出现一次. 如果您在myClass.h内部但在myClass外部定义静态成员,那么在预处理之后,您将在A.cpp和B.cpp的全局范围内复制同一事物的定义。链接器将从A.cpp内部“看到” B.cpp的全局范围,因此在给定的上下文中您将有多个可用的定义,这是一个问题。
所以我的问题是,如果这是一个问题,那么在A.cpp和B.cpp的全局范围内的类myClass的定义为什么不是一个?
解决方案
不,你误解了原因。static
不需要的变量constexpr
只需要初始化一次,因为它在运行时发生。如果同一个变量在运行时被初始化两次,那确实是错误的......因此它们必须在 .cpp 中初始化,以便编译器/链接器知道哪个库带有它。
另一方面,类的定义是编译时定义,因此链接器会丢弃所有重复项。(这实际上是非常糟糕的,会导致编译时间很差,有时还会出现 ODR 问题。开发了 C++20 模块来解决这些问题。)。
推荐阅读
- java - 从地图应用 BiFunction
- github - 查看存储在 GitHub LFS 上的文本文件
- firebase - 在无 SQL 数据库中有效地建模关系
- jakarta-mail - JavaMail-Folder AutoClosable 异常
- apache - Apache:以 Cookie 值为条件的 RewriteRule
- kotlin - Kotlin:具有扩展功能的应用程序
- c# - 在两个视图上显示相同的弹出窗口
- asp.net-core - 如何按照存储库模式在 Asp.Net Core 5.0 项目上实现 .Net Core Identity?
- python - 在 matplotlib 中设置 Y 轴的字符串值
- c++ - 如何在cin之后新建一个动态数组