【问题标题】:How does extern work in c++?extern 在 C++ 中是如何工作的?
【发布时间】:2010-03-25 04:42:20
【问题描述】:

这是来自<iostream>

namespace std 
{
  extern istream cin;       ///< Linked to standard input
  extern ostream cout;  
...

似乎通过使用extern,其他命名空间中定义的数据类型将可用?

【问题讨论】:

    标签: c++ syntax extern


    【解决方案1】:

    extern 表示“这些变量是在其他一些编译单元(.cpp 或 .lib 文件)中定义的”

    在这种情况下,您将 #include &lt;iostream&gt; 放入您的 .cpp 文件中,并且因为 cincout 被声明为 extern,编译器将允许您使用它们而不会抱怨。然后,当链接器运行时,它会查找所有 extern 变量并将其全部排序。

    【讨论】:

    • istream还是cinextern istream cin;的情况下定义在其他单元中?
    • 表示cin 是。这与 类定义 不同,在这种情况下,它位于 iostream 中。 类定义必须始终在编译单元中可用,才能使用该类类型的对象(这就是将类定义放入 header 文件的原因)。
    • cincout 是全局变量。在 C++ 中,必须在一个且仅一个 .cpp 文件中声明全局变量(有一些例外)。因此,如果您只是说istream cin,那么当您链接两个都声明变量的文件时,链接器会抱怨,因为它不知道要使用哪一个。因此,通过将除其中一个之外的所有变量声明为extern,您可以告诉链接器使用非extern 作为“真实”变量,而extern 只是说“此变量在其他一些.cpp 中声明文件”。
    • declaredefine 之间的区别对于理解这一点至关重要。请做对!它们不是同义词。
    【解决方案2】:

    extern 用于引用在不同编译单元中定义的变量(现在,您可以将编译单元视为 .cpp 文件)。您的示例中的语句 declare 而不是 define cincout。它告诉编译器这些对象的定义是在另一个编译单元中找到的(它们声明为extern)。

    【讨论】:

    • 但我没有找到任何定义cin的地方,只有istream&lt;iosfwd&gt;中定义
    • cinistream 类型的对象。 istream 是类(在本例中为模板类)定义。 cinistream 类的一个实例。我在回答中提到的“定义”是cin 的定义,而不是istream。您需要查找 definitiondeclaraion 的含义。您的示例中的陈述是声明
    • cin 变量的定义 很可能在运行时库中。您不会在标准库头文件中找到它。
    • @STingRaySC ,有什么诀窍可以找到它的实际定义位置吗?
    • @symfony:不。它是在已经编译到库中的代码中定义的,您将链接代码。通常,extern 声明所引用的变量可以在链接器可用的任何编译单元中定义(以编译的目标文件的形式)。
    【解决方案3】:

    不,这是一种明确的说法,即声明 cincout 而不实际定义它们。

    【讨论】:

      【解决方案4】:

      extern 关键字告诉编译器一个变量是在另一个源中声明的(即在当前范围之外)。然后链接器找到这个实际声明并设置 extern 变量以指向正确的位置。

      extern 语句声明的变量不会为它们分配任何空间,因为它们应该在别处正确定义。如果一个变量被声明为extern,并且链接器没有发现它的实际声明,它将显示错误。

      例如。 外部 int i;

      //这声明有一个名为 i 的 int 类型的变量,定义在程序的某处。

      【讨论】:

        【解决方案5】:

        这里有些答案说 extern 意味着该变量是在其他编译单元中定义的。然后,以下不应该编译,因为没有其他编译单元或文件提供给编译器。

        extern int a;
        int main(){
            std::cout<<a<<std::endl;    //Prints 3
        }
        int a=3;
        

        所以,我认为 extern 被明确用于分隔声明和定义,以防出现变量,如答案之一所述。我认为在功能的情况下它是无用的。

        【讨论】:

          猜你喜欢
          • 2011-07-03
          • 2012-02-29
          • 2019-12-22
          • 1970-01-01
          • 2023-03-24
          • 2013-12-29
          • 1970-01-01
          • 2014-03-20
          • 1970-01-01
          相关资源
          最近更新 更多