在c++中为用户定义的类型使用extern关键字

using extern keyword for user defined types in c++

本文关键字:类型 extern 关键字 定义 c++ 用户      更新时间:2023-10-16

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

这是我写的程序,但不幸的是我做错了或错过了一些东西,所以我得到编译器错误。

Prog1.cpp

#include <iostream>
using std::cout;
class test
{
     public:
     void fun();
};
void test::fun()
{
    cout<<"fun() in testn";
}
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

因此,解决方案是,在定义类的地方编写test.h,然后像往常一样在Prog2.cpp中定义test t。将test.h包含在Prog2.cpp中,这样它就可以知道test的定义。然后构建它。

test.h:

#include <iostream>
using std::cout;
class test  //definition of test
{
     public:
     void fun()
     {
        cout<<"fun() in testn";
     }
};

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();
}

现在你的代码应该编译和链接了。

注意t的定义是链接器在链接时需要的,所以它会在其他.o文件中搜索它,但是test的定义是编译器在编译时需要的。

现在很明显,你可以把extern test t;放在头文件本身,这样你就不必把它写在每个.cpp文件中,你想使用Prog1.cpp文件中定义的对象(它被编译器转换成Prog1.o)。

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

例如:

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(使用在头文件中已经声明过的定义)

#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();
}

注意:如果在头文件中没有声明对象global_udt,那么main.cpp将不知道它的存在,如果我们试图使用它,编译器将会报错。

所以只需要声明对象,而不是定义对象,因此需要extern关键字。

请注意,在类作用域之外声明的变量是带有外部链接的变量(如果没有显式地使用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是初始化的,而不是仅仅声明,这是因为静态变量在默认情况下被初始化为默认值。