为什么跨不同源文件的多个变量定义是一个问题,但跨不同源的多个 class 定义不是问题
Why is multiple variable definition across different source files a problem, but multiple class definition across different sources is not
我目前在uni学习C++(更准确地说是C++03),我遇到了静态成员的初始化。 Non-constant 静态成员应在 class 内部声明,但在外部定义。此外,它们也应该在源文件中声明,而不是 header 文件。据我了解,那是因为如果你有一个 myClass.h header 和一个 myClass class 和 A.cpp 和 B.cpp 其中包括它,那么你可以保护自己免受多重定义 inside 具有包含保护的相同源文件,但您无法防止 myClass.h 出现一次在 A.cpp 中,一次在 B.cpp 中。如果在 myClass.h 内部定义静态成员,但在 myClass 外部定义静态成员,那么在预处理之后,您将复制相同的定义A.cpp 和 B.cpp 的全局范围内的东西。链接器将从 A.cpp 和 vicecersa 内部 "see" B.cpp 的全局范围,所以你会在给定上下文中有多个可用定义,这是一个问题。
所以我的问题是,如果这是一个问题,那么 class myClass 的定义为什么都在 的全局范围内A.cpp 和 B.cpp 不是一个吗?
不,你理解错了原因。 static
不是 constexpr
的变量只需要初始化一次,因为它发生在 运行 时间。如果同一个变量在 运行 时间被初始化两次,那肯定是错误的...因此它们必须在 .cpp 中初始化,以便 compiler/linker 知道哪个库携带它。
另一方面,类 的定义是编译时定义,因此链接器会丢弃所有重复项。 (这实际上非常糟糕,会导致编译时间很短,有时会导致 ODR 问题。开发模块 C++20 就是为了解决这些问题。)
你有些概念是错误的,这没关系,每个人都会有。你看,没有硬性规定非静态方法的定义要写在 class 中。即使将它们写在 class 之外也很好,不同之处在于,如果需要,您可以屏蔽它们的定义,因为头文件需要以明文形式提供。与此相反,如果您不在 .cpp
文件中编写函数,则不能 make a library and provide the library, inherently masking the definitions. Also, it is usually recommended to do it the former way, so that the class size in clear text becomes small and the abstraction is better achieved. Also, please do read how to ask a good question on stack overflow.
回复:如果你在 myClass.h 内部定义静态成员,但在 myClass 外部,那么在预处理之后,你将在 A.cpp 的全局范围内和B.cpp请阅读boilerplate code
希望这对您有所帮助。 :)
如果你什么都不明白,我随时欢迎讨论;不要犹豫,问
我目前在uni学习C++(更准确地说是C++03),我遇到了静态成员的初始化。 Non-constant 静态成员应在 class 内部声明,但在外部定义。此外,它们也应该在源文件中声明,而不是 header 文件。据我了解,那是因为如果你有一个 myClass.h header 和一个 myClass class 和 A.cpp 和 B.cpp 其中包括它,那么你可以保护自己免受多重定义 inside 具有包含保护的相同源文件,但您无法防止 myClass.h 出现一次在 A.cpp 中,一次在 B.cpp 中。如果在 myClass.h 内部定义静态成员,但在 myClass 外部定义静态成员,那么在预处理之后,您将复制相同的定义A.cpp 和 B.cpp 的全局范围内的东西。链接器将从 A.cpp 和 vicecersa 内部 "see" B.cpp 的全局范围,所以你会在给定上下文中有多个可用定义,这是一个问题。
所以我的问题是,如果这是一个问题,那么 class myClass 的定义为什么都在 的全局范围内A.cpp 和 B.cpp 不是一个吗?
不,你理解错了原因。 static
不是 constexpr
的变量只需要初始化一次,因为它发生在 运行 时间。如果同一个变量在 运行 时间被初始化两次,那肯定是错误的...因此它们必须在 .cpp 中初始化,以便 compiler/linker 知道哪个库携带它。
另一方面,类 的定义是编译时定义,因此链接器会丢弃所有重复项。 (这实际上非常糟糕,会导致编译时间很短,有时会导致 ODR 问题。开发模块 C++20 就是为了解决这些问题。)
你有些概念是错误的,这没关系,每个人都会有。你看,没有硬性规定非静态方法的定义要写在 class 中。即使将它们写在 class 之外也很好,不同之处在于,如果需要,您可以屏蔽它们的定义,因为头文件需要以明文形式提供。与此相反,如果您不在 .cpp
文件中编写函数,则不能 make a library and provide the library, inherently masking the definitions. Also, it is usually recommended to do it the former way, so that the class size in clear text becomes small and the abstraction is better achieved. Also, please do read how to ask a good question on stack overflow.
回复:如果你在 myClass.h 内部定义静态成员,但在 myClass 外部,那么在预处理之后,你将在 A.cpp 的全局范围内和B.cpp请阅读boilerplate code
希望这对您有所帮助。 :) 如果你什么都不明白,我随时欢迎讨论;不要犹豫,问