Chinaunix首页 | 论坛 | 博客
  • 博客访问: 170496
  • 博文数量: 84
  • 博客积分: 3742
  • 博客等级: 中校
  • 技术积分: 870
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-20 19:38
文章分类

全部博文(84)

文章存档

2012年(6)

2011年(21)

2010年(54)

2009年(3)

分类: LINUX

2011-04-24 09:24:45

一、
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
当去掉代码中注释行后,可编译成功
 
阅读(747) | 评论(0) | 转发(0) |
0

上一篇:cvCreateImage()简介

下一篇:进程间关系

给主人留下些什么吧!~~