c++ - 关于ODR、声明和定义的一些问题

标签 c++ class static-members definition one-definition-rule

对不起,如果问题是旧的或有点愚蠢。

我知道声明和定义的基础知识,但在 C++ 中似乎有很多不一致 或“异常”,这使得它不和谐,至少对我而言。或者,我误解了什么。

所以,在头文件中,我们声明一些变量和定义类类型(也听说过“类声明”,不知道哪个更准确);在每个类中,我们声明成员变量和函数。然后在一些.cc/.cpp 文件中,我们只定义实现该类的成员函数。如果“不幸”有一个静态成员变量/函数,它会被认为是特殊的并且完全独立于关联的类,它必须在类之外定义,作为唯一的“怪胎” "在成员变量之间。

当一个 .cpp 文件#include是一个定义类类型的头文件时(请注意,该头文件中的类类型定义似乎“不完整”,因为它的函数在其他地方定义。),.cpp 文件将类类型定义放在开头,以及其他可能的声明

在.cpp文件中,#included类的静态成员变量已经在实现.cpp中定义,还有成员函数,那怎么办如果创建类的实例,非静态“普通”成员变量?假设是Class A;,那么如果A a;,非静态成员变量会被定义吗?当然 A 类型的对象 a定义的,但是它的非静态成员变量是否也被定义 (在分配内存的意义上定义)?如果是这样,那么相同类型 A 的两个对象,例如 a1a2 完全可以放在一起,因为 a1 .mem_var_1a2.mem_var_1 对于不同的类实例名称有不同的定义?或者,它们共享“相同的定义”但具有不同的值和拷贝?

成员函数呢?它们已经在类类型的.cpp文件中定义,但是当我们创建多个实例时,它们是否在.cpp中共享相同的定义但具有不同的内存中的拷贝(我想至少对于内部局部变量的不同值,同一成员函数的多个拷贝是必要的)?静态函数呢?

或者,我误解了什么,因为我们程序员定义”文件中的某些东西不等于编译器和链接器定义”文件中的内容? 定义的真正作用和含义是什么?我们在文件中写入“定义”一些东西,但系统可以“定义”不同的东西,至少在 secret 制作多个拷贝和东西的意义上是这样?

我头疼...

最佳答案

这背后的原因是历史原因。当 C 被发明时,内存和处理器又小又贵。如果您的项目有 20 个文件,编译器就无法将所有文件加载到内存中并解析符号。 Resolve 是指为每个函数、结构和变量分配足够和正确的空间。

现在,假设我们有 2 个 cpp 文件,一个定义 struct String,另一个定义 struct Rectangle。为了让函数在两个文件中都使用 String 和 Rectangle,编译器需要加载这两个文件并分析它们。在那些时候,这将是一个非常占用内存的操作。

因此,一些额外的文件,标题被采纳了。这些 header 只是告诉编译器有关 cpp 使用的每种类型的内存信息。然后编译器能够仅基于 cpp 文件和所有依赖的头文件编译成 obj 文件。

所有的cpp编译完成之后,就是链接,所有的obj文件都放在一起。现在重要的是变量在所有 cpp 中以相同的方式定义,否则一些 cpp 将使用 8 字节的矩形,而另一个 cpp 将使用 12 字节的矩形,当放在一起时 -> 砰!

关于c++ - 关于ODR、声明和定义的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31278221/

相关文章:

类似于eternity的C++对象持久化库

c++ - 将变量定义为自动限制

c++ - 结构/类中静态常量的奇怪 undefined symbol

c++ - 我不明白这个快速排序的实现

c++ - 将 map 键与 comboBox.currentText() 进行比较时应用程序崩溃;

python - 如何在Python中的子方法中访问从父类获得的init变量?

php - 是否有与 PDO::FETCH_CLASS 等效的 INSERT 或 UPDATE?

python - 按需执行存储在变量中的类函数

java - 静态成员的方法是否被视为静态?

c++ - 在模板类中初始化静态指针