对不起,如果问题是旧的或有点愚蠢。
我知道声明和定义的基础知识,但在 C++ 中似乎有很多不一致 或“异常”,这使得它不和谐,至少对我而言。或者,我误解了什么。
所以,在头文件中,我们声明一些变量和定义类类型(也听说过“类声明”,不知道哪个更准确);在每个类中,我们声明成员变量和函数。然后在一些.cc/.cpp 文件中,我们只定义实现该类的成员函数。如果“不幸”有一个静态成员变量/函数,它会被认为是特殊的并且完全独立于关联的类,它必须在类之外定义,作为唯一的“怪胎” "在成员变量之间。
当一个 .cpp 文件#include
是一个定义类类型的头文件时(请注意,该头文件中的类类型定义似乎“不完整”,因为它的函数在其他地方定义。),.cpp 文件将类类型定义放在开头,以及其他可能的声明。
在.cpp文件中,#include
d类的静态成员变量已经在实现.cpp中定义,还有成员函数,那怎么办如果创建类的实例,非静态“普通”成员变量?假设是Class A;
,那么如果A a;
,非静态成员变量会被定义吗?当然 A
类型的对象 a
是定义的,但是它的非静态成员变量是否也被定义 (在分配内存的意义上定义)?如果是这样,那么相同类型 A
的两个对象,例如 a1
和 a2
完全可以放在一起,因为 a1 .mem_var_1
和a2.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/