在编译程序的时候,遇到了一个问题,花点时间记录一下:
在Qt中创建一个类后,一般是先在.h文件中声明变量与函数,然后在对应的.cpp文件中对各个函数进行定义,这在往常使用中没有任何问题,今天在使用Qt时,在各.cpp源文件编译时出现了许多multiple definition of XXX的错误。
搜寻了网上一些资料,总算是解决multiple definition of 的方法:
问题解决方法之一:
根据网上的解释,multiple definition of 原因是因为在多次包含global.h时重复定义了变量和函数。问题是检查过程序后,发现并不存在重复定义的变量和函数,在一条论坛评论中尝试了一种简单粗暴的方法……以Qt项目为例,在项目的Debug文件夹中找到编译时生成的o文件,如:
c和c++编译.c,cpp文件,每个文件都生成.o文件,再把所有的.o文件链接成最后的执行程序,若o文件有问题,是无法生成执行文件的。将已存在的o文件删除之,重新编译并生成新的o文件,结果在没有其他问题的情况下成功生成执行程序。(我就是属于这种情况…在确认代码中已无明显错误时可以一试)
问题解决方法之二:
当多个文件包含同一个头文件时,并且你的.h文件里面没有加上条件编译。
而当多个文件包含同一个头文件时,而头文件中没有加上条件编译,就会独立的解释,然后生成每个文件生成独立的标示符。在编译器连接时,就会将工程中所有的符号整合在一起,由于,文件中有重名变量,于是就出现了重复定义的错误。
给每一个头文件加上条件编译,避免该文件被多次引用时被多次解释,这是个应该是习惯。这个方法会解决大部分低级问题。在创建Qt类时已默认生成条件编译:
#ifndef TEST_H
#define TEST_H
......
#endif
就会独立的解释,然后生成每个文件生成独立的标示符。在编译器连接时,就会将工程中所有的符号整合在一起,由于,文件中有重名变量,于是就出现了重复定义的错误。
因此可以给每一个头文件加上条件编译,避免该文件被多次引用时被多次解释,这是个应该是习惯。这个方法会解决大部分低级问题。
问题解决方法之三:
当以上方法无效时,可以把所有的全局变量放入一个头文件 global.h (名字随意起,但要加条件编译)中,每一个变量前面加extern,声明一下这些变量将在其它文件中定义。 然后建立一个和头文件名字对应的.c or .cpp文件 如global.c。在里面声明所有的全局变量。例如:void(*Handl_Display)();
然后,让涉及到全局变量的文件include ”global.h“。这样编译时,会先对global.c编译生成一个global.o ,然后再和其它文件的.o链接生成可执行文件。
在一篇文章: http://blog.csdn.net/wu070815/article/details/8781762 中提到的另一种解决方法:
在变量前加static,声明成静止变量。
这个方法虽然可以解决multiple definition的问题,但是却会引发其他问题。
问题如下:
三个文件,a.h,a.c,b.c;
在a.c和b.c 都include了a.h。
在b.c中调用a.c中的函数对a.h中的变量进行赋值,但事实上b.c中的变量仍没被赋值。
问题分析:
static的含义是迫使那个变量只在某个文件可见。
假定你在头文件定义static x;
且这个头文件分别被a.c和b.c包含;
实质是在a.c和b.c里会分别定义一个名字叫x的变量,两个x毫无关系。
在a.c里修改x,他不会导致b.c里的x变化。