关于重定义

1

现在有一个程序,有一个头文件和两个源文件。头文件定义了一个变量Height,然后源文件开头都包含了这个头文件;
现在调试,出现

picture.obj : error LNK2005: "int Height" (?Height@@3HA) already defined in main.obj
Debug/拼图2_0.exe : fatal error LNK1169: one or more multiply defined symbols found
执行 link.exe 时出错.

我在头文件在这个变量定义前加了extern,还是一样的错误。这个错误到底是怎么回事呢?我粗略学过作用域,不太理解

0

问题原因

每个 cpp 文件都会编译成 obj 然后再链接。于是,你的两个 cpp 通过引用同一个头文件,就会使两个 cpp 文件编译成的 obj 里面都有一个 int Height 变量。然后在链接步骤将两个 obj 文件链接,就会造成 Height 变量已经定义的错误。

解决办法

使用函数时,需要“定义函数”,同时需要在使用函数之前“声明函数”。

同理,使用全局变量时,需要“定义全局变量”,然后在使用全局变量之前用 extern 关键字“声明全局变量”(即外部变量)。

示例代码

以下示例包含三个文件:c1.cpp、c2.cpp、d.h,代码如下。

c1.cpp:

#include "d.h"

int main()
{
	g_num = 3;
	printf("%d\n", mytest());
	return 0;
}

c2.cpp:

#include "d.h"

// 定义全局变量 g_num(也可以定义在 c1.cpp,但只能在一个地方定义)
int g_num;

// 定义函数 mytest
int mytest()
{
	return g_num * 2;
}

d.h:

#pragma once

#include <stdio.h>
extern int g_num;	// 声明外部变量 g_num
int mytest();		// 声明函数 mytest

编译执行,即可看到效果。

ava
慢羊羊

2020-3-25

我的编译器是vc++6.0,加了还是没有效果 -  看到这个菜鸡请催它学习  2020-3-26
@看到这个菜鸡请催它学习 我已经修正了我的答案。 -  慢羊羊  2020-3-26
@慢羊羊  要怎么在头文件声明?直接加好像还是定义吧? 这里有两种操作:头文件均是在原有的int Height前加了“extern”。我在一个cpp文件引用头文件前定义Height,错误信息picture.obj : error LNK2005: "int Height" (?Height@@3HA) already defined in main.obj
Debug/拼图2_0.exe : fatal error LNK1169: one or more multiply defined symbols found 和原来的一样; 在引用头文件后定义Height,错误信息是picture.cpp(15) : error C2086: 'Height' : redefinition,还是重定义?
 -  看到这个菜鸡请催它学习  2020-3-26
@看到这个菜鸡请催它学习 看我最新修改后的答案。 -  慢羊羊  2020-3-26
@慢羊羊  特别感谢!不过我这里没有用到函数。我思考了你的做法,发现操作的区别在于:原来的头文件是给Height赋了值。现在把定义赋值操作转移到一个cpp文件,把头文件中的变成extern int Height,就可以运行了。 -  看到这个菜鸡请催它学习  2020-3-26
技术讨论社区
相关提问