在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 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是初始化的,而不是仅仅声明,这是因为静态变量在默认情况下被初始化为默认值。
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 为什么在全局范围内使用"extern int a"似乎不行?
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 是否可以在不使用 decltype 的情况下推断先前定义的 extern 变量的类型
- 如何使用模板 extern 关键字分隔测试类型
- 为什么 Extern-C 返回 POD 和构造类型的方式不同
- 在c++中为用户定义的类型使用extern关键字