一、
main.cpp
#include "global.h"
int Main(....)
{
...
}
file_1.cpp
#include "global.h"
....
file_2.cpp
#include "global.h"
...
global.h中写有所有的全局变量及其初始化值 和函数声明
在编译的时候就会出错:
first defined here
multiple definition of
原因是因为在多次包含global.h时重复定义了变量和函数。
解决方法:
方法一:
在global.c(或.cpp) 中声明变量(不初始化),然后头文件global.h中在所有的变量声明前加上extern
如 extern int flag;
然后在其他需要使用全局变量的 cpp文件中包含.h 文件而不要包含 .cpp 文件。编译器会为global.cpp 生成目标文件,然后连接时,在使用全局变量的文件中就会连接到此文件 。
方法二:
在global.h中加入防止多次重复定义的宏判断符号
你的.H里面要加上条件编译
#ifndef GLOBAL
#define GLOBAL
XXXXX
XXXXX
#endif
记住:在ifndef时一定要在第一行,前边不要有任何的注释或语句。
二、
multiple definition of XXX
实验室里的学习 2009-04-25 21:22:35 阅读858 评论1 字号:大中小
明明只定义了一次变量XXX,却被编译器告知:multiple definition of XXX
奇怪中,猜测,可能是与头文件的include有关。
代码如下:
// ic.h
#ifndef __IC_H__
#define __IC_H__
float hisRatio=0.1;
/* other part omitted*/
#endif
//ic.cpp
#include "ic.h"
float tmpValue=hisRatio;
/*other part omitted*/
编译输出信息:
/tmp/ccAHyLaX.o:(.data+0x0): multiple definition of `hisRatio'
/tmp/ccLrvuCE.o:(.data+0x0): first defined here
想找到问题的找了很久,未果。
后来,参照别的常数的使用情况,在hisRatio的定义前面加上了const修饰。因为,在这个工程中,hisRation确实起到一个全局的常量。
结果,编译成功,问题消失了。
O,原来如此。
hisRatio是在另外的文件中定义的,如果是变量的话,在不同的文件中使用的话一般要求使用前加上extern修饰声明。
而,我的这个想被include进来使用。
总言之,常量前面加上const,就在所有include它的文件中可用了
三、
总结了解决multiple definition of的方法:
问题原因:
当多个文件包含同一个头文件时,并且你的.H里面没有加上条件编译
#ifndef TEST_H
#define TEST_H
#endif
就会独立的解释,然后生成每个文件生成独立的标示符。在编译器连接时,就会将工程中所有的符号整合在一起,由于,文件中有重名变量,于是就出现了重复定义的错误。
方法1:
给每一个头文件加上条件编译,避免该文件被多次引用时被多次解释,这是个应该是习惯。这个方法会解决大部分低级问题。
方法2:
当方法1无效时,可以把所有的全局变量放入一个头文件 global.h (名字随意起,但要加条件编译)中,每一个变量前面加extern,声明一下这些变量将在其它文件中定义。 然后建立一个和头文件名字对应的.c or .cpp文件 如global.c。在里面声明所有的全局变量。例如:void(*Handl_Display)();
然后,让涉及到全局变量的文件include ”global.h“。这样编译时,会先对global.c编译生成一个global.o ,然后再和其它文件的.o链接生成可执行文件。
方法3:
懒人方法,在所有的全局变量前加上static ,声明成静止变量。也能解决问题。
所有的方法都是网来的,O(∩_∩)O哈哈~
谢谢所有的提供方法的哥们~
四、
下午研究代码的时候,出现multiple definition of xxx之类的错误,通过查资料,解决。
There are three kinds of global symbols, illustrated here by C examples:
`int i = 1;'
A definition, which goes in the initialized data section of
the output file.
`extern int i;'
An undefined reference, which does not allocate space. There must be either a definition or a common symbol for the variable somewhere.
`int i;'
A common symbol. If there are only (one or more) common
symbols for a variable, it goes in the uninitialized data
area of the output file. The linker merges multiple common
symbols for the same variable into a single symbol. If they are of different sizes, it picks the largest size. The linker turns a common symbol into a declaration, if there is a definition of the same variable.
-----------------------------------------------------------
1. 如果*只*有上面说的第二种symbol("undefined reference"), 那linker会报错"undefined
reference".
2. 如果有多于一个的"definition"(上面说的第一种symbol), 那linker会报错"multiple
definition of 'XXX'".
3. 对其它情况, it's all okay.
五、
源码:tem.h中定义Tem类
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class Tem : public QWidget
{
Q_OBJECT //请关注此处
public:
Tem(QWidget * parent=0, Qt::WFlags fl=0);
~Tem(){};
private slots: //请关注此处
void readTem();
private:
int fd ;
unsigned int tmp;
QTimer * t;
QLabel * label1;
QLabel * label2;
QLabel * label3;
QLabel * label4;
QLabel * label5;
QLabel * label6;
QComboBox * box1;
QComboBox * box2;
QPushButton * button1;
QPushButton * button2;
};
Tem::Tem(QWidget * parent, Qt::WFlags fl):QWidget(parent, fl)
{
setWindowTitle("温度测控");
setGeometry(10,40,220,140);
label1= new QLabel("当前温度:");
label2= new QLabel("warning ");
label3= new QLabel("上限:");
label4= new QLabel("下限:");
label5= new QLabel("报警开关:");
label6= new QLabel;
box1 =new QComboBox;
box1->addItem("28", 28);
box1->addItem("25", 25);
box2= new QComboBox;
box2->addItem("12", 12);
box2->addItem("14", 14);
button1= new QPushButton("报警:");
button2= new QPushButton("停止:");
QHBoxLayout * h1= new QHBoxLayout;
QHBoxLayout * h2= new QHBoxLayout;
QHBoxLayout * h3= new QHBoxLayout;
QHBoxLayout * h4= new QHBoxLayout;
QHBoxLayout * h5= new QHBoxLayout;
h1->addWidget(label1);
h1->addWidget(label6);
h2->addWidget(label2);
h3->addWidget(label3);
h3->addWidget(box1);
h4->addWidget(label4);
h4->addWidget(box2);
h5->addWidget(label5);
h5->addWidget(button1);
h5->addWidget(button2);
QVBoxLayout * v= new QVBoxLayout;
v->addLayout(h1);
v->addLayout(h2);
v->addLayout(h3);
v->addLayout(h4);
v->addLayout(h5);
setLayout(v);
/* fd = open("/dev/18b20", 0);
if(fd < 0)
{
perror("Can't open /dev/18b20 \n");
exit(1);
}
printf("open ds18b20 success \n");*/
// t= new QTimer(this);
// connect(t, SIGNAL(timeout()), this, SLOT(readTem()));
// t->start(3000);
}
void Tem::readTem()
{
read(fd, &tmp , sizeof(int));
printf("the currently temperature is %d \n",tmp);
label6->setText((char *)tmp);
}
编译的错误信息如下;
moc_tem.o(.text+0x0): In function `Tem::Tem(QWidget*, QFlags)':
: multiple definition of `Tem::Tem(QWidget*, QFlags)'
main.o(.text+0x0): first defined here
moc_tem.o(.text+0x1320): In function `Tem::Tem(QWidget*, QFlags)':
: multiple definition of `Tem::Tem(QWidget*, QFlags)'
main.o(.text+0x1320): first defined here
moc_tem.o(.text+0x2640): In function `Tem::readTem()':
: multiple definition of `Tem::readTem()'
main.o(.text+0x2640): first defined here
collect2: ld returned 1 exit status
make: *** [tem] 错误 1
当去掉代码中注释行后,可编译成功
阅读(1607) | 评论(0) | 转发(0) |