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



如果问题陈旧或有点愚蠢,请原谅。

我知道声明和定义的基础知识,但c++中似乎有很多不一致或"异常",这使得它不和谐,至少对我来说是这样。或者,我误解了什么。

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

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

在.cpp文件中,#include d类的静态成员变量已经定义,在实现的。cpp中与成员函数一起定义,那么如果创建了类的实例,那么非静态的"正常"成员变量怎么办?假设它是Class A;,那么非静态成员变量将定义如果A a; ?当然,A类型的对象a定义的,但是它的非静态成员变量是否也得到定义的(在分配内存的意义上定义的)?如果是这样,那么两个对象,比如a1a2,相同类型的A将完全可以在一起,因为a1.mem_var_1a2.mem_var_1对于不同的类实例名具有不同的定义 ?或者,它们共享"相同的定义",但具有不同的值和副本?

成员函数呢?他们已经定义在类类型的。cpp文件,但是当我们创建多个实例,他们不会共享相同的定义在。cpp,但在内存中有不同的副本(我猜相同的成员函数的多个副本是必要的,至少对于不同的值的局部变量)?那么静态函数呢?

或者,我误解了一些东西,因为我们程序员"定义"文件中的东西不等于编译器和链接器"定义"文件中的东西?定义的真正含义是什么?我们在文件中写"定义"的东西,但是系统可以"定义"不同,至少在秘密地制作多个副本和东西的意义上?

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

现在,假设我们有两个cpp文件,一个定义结构体String,另一个定义结构体Rectangle。为了让函数在两个文件中处理String和Rectangle,编译器需要加载两个文件并分析它们。这些时候,这将是一个非常内存密集型的操作。

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

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

相关内容

  • 没有找到相关文章

最新更新