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

时间:2015-07-07 20:01:43

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

如果问题陈旧或有点愚蠢,请抱歉。

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

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

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

在.cpp文件中,实现.cpp中#include d类的静态成员变量已经定义以及成员函数,那么非静态的呢?如果创建了类的实例,则为“普通”成员变量?假设它是Class A;,那么如果A a;,那么非静态成员变量是定义吗?当然,a类型的对象A 已定义,但其非静态成员变量也会已定义已定义< / strong>在分配内存的意义上)?如果是这样,那么同一类型a1的两个对象(例如a2A)可以完全合并,因为a1.mem_var_1a2.mem_var_1有所不同关于不同类实例名称的定义?或者,他们分享“相同的定义”但具有不同的值和副本?

会员职能怎么样?它们在.cpp文件中已经定义用于类类型,但是当我们创建多个实例时,它们不会在.cpp中共享相同的定义但是有不同的内存中的副本(我想至少对于局部变量里面的不同值,需要多个相同成员函数的副本)?静态函数怎么样?

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

我的头疼......

1 个答案:

答案 0 :(得分:-1)

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

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

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

在编译了所有cpp之后,会出现链接,其中所有obj文件都放在一起。现在关键是变量在所有cpp中以相同的方式定义,否则一些cpp将使用8字节的Rectangle,而另一个cpp将使用12字节的Rectangle,并且当放置时在一起 - &gt;砰!