Published

11 October 2013

Tags

Contents

当你#include的头文件包含了一些全局函数或者变量的定义,并且这个头文件被多个 cpp 文件引用时,Qt一定会返回重定义链接错误,即使你的头文件里有#ifndef这样的代码。

这是为什么呢?仔细观察qmake生成的makefile文件,可以发现他做的事情是把不同的 *.cpp 文件编译成 *.o ,然后再一口气把所有编译成 .exe,问题就出在这里,不同的 *.o 文件因为 #include 了这个头文件,而都包含了这些全局函数变量的定义,于是乎就出错了。

要解决全局变量的问题,加个extern就好了,表示这是个全局变量的声明而不是定义。

要解决全局函数的问题,一个方法是把函数写到类里面就可以编译过了,注意下面两种写法:

struct A {
    void haha() {};
};

struct B {
    void haha();
}

void B::haha() {}

A 是可以编译通过的,但是 B 却不行,对编译原理不是很了解,可能是因为void B::haha() {}被当做一个全局函数定义。

于是为了让 B 编译过,把函数放到里面就好了。

但是碰到某些情况是必须写在外部的,比如类的相互引用:

struct A;
struct B;

struct A {
    B *b;
    void haha();
}

struct B {
    A *a;
    void haha();
}

void A::haha() {b=b->a->b;}
void B::haha() {a=a->b->a;}

解决办法是把定义分开写到 cpp 里。

当这个头文件要作为一个库的时候,你就需要将 cpp 编译成 lib,然后链接,但是有时自己写的库不想编译成lib,因为不方便管理,于是乎有一个蛋疼的方法是,吧cpp文件也放到 include 目录里,然后让你的某一个文件 #include 你的这个 cpp 就好了,这样函数就只会定义一次。



blog comments powered by Disqus