在 C++ 中对用户定义的类型使用 extern 关键字

using extern keyword for user defined types in c++

我想对用户定义的类型使用 extern 关键字。这意味着我在一个文件中声明了对象并在另一个文件中定义了它。我读过 extern 关键字用于声明变量而不定义它。当程序被拆分成多个源文件并且每个源文件都需要使用全局变量时,extern 关键字很有用。如果我哪里错了,请指正。

这是我编写的程序,但不幸的是我做错了什么或遗漏了什么,所以我遇到了编译器错误。

Prog1.cpp

#include <iostream>
using std::cout;
class test
{
     public:
     void fun();
};
void test::fun()
{
    cout<<"fun() in test\n";
}
test t; 

Prog2.cpp

#include <iostream>
using std::cout;
extern test t;
int main()
{
    t.fun();
}

现在当我使用

编译这两个

g++ -o prog1.cpp prog2.cpp

编译器在 prog2.cpp

中给出了以下错误
error: 'test' does not name a type

error:  't' was not declared in this scope

请帮助我知道我在这里做错了什么。

extern 告诉编译器 t 的定义在别处,但编译器仍然需要 test 的定义,因为您正在使用 t.fun() 编译 Prog2.cpp.

所以解决方法是,在定义class的地方写test.h,然后像往常一样在Prog2.cpp中定义test t。在你的 Prog2.cpp 中包含 test.h 以便它可以知道 test 的定义。然后构建它。

test.h:

#include <iostream>

using std::cout;

class test  //definition of test
{
     public:
     void fun()
     {
        cout<<"fun() in test\n";
     }
};

Prog1.cpp:

#include "test.h"

test t;  //definition of t

Prog2.cpp:

#include <iostream>

#include "test.h"

using std::cout;

extern test t; //the definition of t is somewhere else (in some .o)
               //and the definition of test is in test.h
int main()
{
    t.fun();
}

现在您的代码应该可以编译并且 link。

注意 t 的定义是 link-time 的 linker 需要的,因此它将在其他 .o 文件中搜索它,但是定义编译器需要 test,位于 compile-time。

现在应该很明显,您可以将 extern test t; 放在 header 本身中,这样您就不必在每个要使用的 .cpp 文件中都写它object 在 Prog1.cpp 文件中定义(由编译器转换为 Prog1.o)。

extern 关键字放在 header 中,而不是 cpp文件。 header 的工作是告诉编译器某处有一个 外部定义的 object。

For example:

program.h(主要是声明)

struct UserDefinedType
{
    void do_stuff();
};

// declare your global object in the header
// so that the compiler knows its name when
// compiling sources that can not otherwise see
// the object
extern UserDefinedType global_udt;

program.cpp(主要是定义)

#include "program.h"

// define the member functions here
void UserDefinedType::do_stuff()
{
}

// define the global object here
UserDefinedType global_udt;

main.cpp(使用在header)

#include "program.h" // tells the compiler about global_udt

int main()
{
    // call the global object that is defined
    // in a different source file (program.cpp)
    global_udt.do_stuff();
}

注意: 如果我们没有声明 object global_udt header 文件然后 main.cpp 将不知道它的存在,如果我们尝试使用它编译器会报错。

所以 header 只需要 声明 object 而不是 定义 因此需要 extern 关键字。

请注意,在 class 范围之外声明的变量是具有外部链接的变量(如果未明确使用 static 关键字)或具有内部链接(如果static关键字放在变量类型的左边),extern如果你想在多个文件中使用它是必要的。

假设这个文件名为MyVariable.h

int myNumber = 0; // Initialization of the variable myNumber, external linkage
static int myStaticNumber; // Initialization of the variable myStaticNumber, internal linkage(only the file in which it's declared)

而这个文件是OtherFile.cpp

extern int myNumber; // Not a initialization because it's already initialized in another file, works fine
extern int myStaticNumber; // ERROR, this variable has internal linkage!!

您可能想知道为什么 myStaticNumber 被初始化而不只是声明,这是因为 static 变量默认初始化为其默认值。