我目前在uni学习C++(更准确的说是C++03),遇到了静态成员的初始化问题。非常态静态成员应该在类内声明,但在类外定义,而且,它们也应该在源文件中声明,而不是头文件。此外,它们也应该在源文件中声明,而不是头文件。据我了解,这是因为如果你有一个 myClass.h 头部有一个 myClass 在其中,并 A.cpp 和 B.cpp 包括它,那么你就可以保护自己免受多重定义的影响。里面 同样的源文件,有了包含保护,但你却不能保护它免受 我的类.h 曾经出现在 A.cpp 而一旦 B.cpp. 如果你在 myClass.h,但在 myClass然后,在预处理之后,你会在全局范围内复制同样的东西的定义。A.cpp 和 B.cpp. 链接器将 "看到 "全局范围的 B.cpp 从内部 A.cpp 和vicecersa,所以在给定的上下文中你会有多个定义,这是个问题。
所以我的问题是,如果这是一个问题,那为什么类的定义是 myClass 在全球范围内 A.cpp 和 B.cpp 是不是一个?
不,你误解了原因。static
非常态的变量,应该在类内声明,而在类外定义。constexpr
只需要初始化一次,因为它是在运行时发生的。如果同一个变量在运行时被初始化两次,那就真的有问题了...。因此,它们必须在.cpp中被初始化,这样编译器linker就知道哪个库携带了它。
另一方面,类的定义是编译时的定义,所以linker会扔掉所有重复的变量。(这其实是非常不好的,会导致编译时间差,有时还会出现ODR问题。C++20模块就是为了解决这些问题而开发的)。)
你把一些概念弄错了,这都是对的,每个人都会有这样的情况。你看,没有硬性规定非静态方法的定义要写在类里面。它甚至完全可以把它们写在类外,不同的是,如果你想的话,你将能够掩盖它们的定义,因为头文件需要以明文方式提供。与此相对应的是,如果你不把函数写在一个 .cpp
文件,你不能 建库 并提供库,本质上掩盖了定义。另外,通常建议采用前一种方式,这样明文中的类体积变小,抽象效果更好。另外,请务必阅读 如何在堆栈溢出上提出一个好问题.
RE: 如果你在myClass.h内定义了静态成员,但在myClass外定义了静态成员,那么在预处理后,你会在A.cpp和B.cpp的全局范围内复制了同一个东西的定义。底板代码
希望这对你有帮助。:)如果你有什么不明白的地方,我随时欢迎你来讨论,不要犹豫,可以问我。