为什么跨不同源文件的多变量定义是个问题,而跨不同源的多类定义就不是问题?

问题描述 投票:-1回答:2

我目前在uni学习C++(更准确的说是C++03),遇到了静态成员的初始化问题。非常态静态成员应该在类内声明,但在类外定义,而且,它们也应该在源文件中声明,而不是头文件。此外,它们也应该在源文件中声明,而不是头文件。据我了解,这是因为如果你有一个 myClass.h 头部有一个 myClass 在其中,并 A.cppB.cpp 包括它,那么你就可以保护自己免受多重定义的影响。里面 同样的源文件,有了包含保护,但你却不能保护它免受 我的类.h 曾经出现在 A.cpp 而一旦 B.cpp. 如果你在 myClass.h,但在 myClass然后,在预处理之后,你会在全局范围内复制同样的东西的定义。A.cppB.cpp. 链接器将 "看到 "全局范围的 B.cpp 从内部 A.cpp 和vicecersa,所以在给定的上下文中你会有多个定义,这是个问题。

所以我的问题是,如果这是一个问题,那为什么类的定义是 myClass 在全球范围内 A.cppB.cpp 是不是一个?

c++ static global member definition
2个回答
1
投票

不,你误解了原因。static 非常态的变量,应该在类内声明,而在类外定义。constexpr 只需要初始化一次,因为它是在运行时发生的。如果同一个变量在运行时被初始化两次,那就真的有问题了...。因此,它们必须在.cpp中被初始化,这样编译器linker就知道哪个库携带了它。

另一方面,类的定义是编译时的定义,所以linker会扔掉所有重复的变量。(这其实是非常不好的,会导致编译时间差,有时还会出现ODR问题。C++20模块就是为了解决这些问题而开发的)。)


1
投票

你把一些概念弄错了,这都是对的,每个人都会有这样的情况。你看,没有硬性规定非静态方法的定义要写在类里面。它甚至完全可以把它们写在类外,不同的是,如果你想的话,你将能够掩盖它们的定义,因为头文件需要以明文方式提供。与此相对应的是,如果你不把函数写在一个 .cpp 文件,你不能 建库 并提供库,本质上掩盖了定义。另外,通常建议采用前一种方式,这样明文中的类体积变小,抽象效果更好。另外,请务必阅读 如何在堆栈溢出上提出一个好问题.

RE: 如果你在myClass.h内定义了静态成员,但在myClass外定义了静态成员,那么在预处理后,你会在A.cpp和B.cpp的全局范围内复制了同一个东西的定义。底板代码

希望这对你有帮助。:)如果你有什么不明白的地方,我随时欢迎你来讨论,不要犹豫,可以问我。

© www.soinside.com 2019 - 2024. All rights reserved.