繁体   English   中英

如何避免链接器错误

[英]How to avoid linker error

内部General.h

#ifndef GENERAL
#define GENERAL
namespace counternamespace{
    int upperbound;
    int lowerbound;
}
#endif

Inside Analyzer.h

#ifndef ANALYZER
#define ANALYZER
#include"General.h"

class Analyzer
{
public :
     int var ;
     int func();
};
#endif

内部Test.h

#ifndef TEST
#define TEST
#include"Analyzer.h" //Error
class Test2
{
public:
    Test2(void);

public:
    ~Test2(void);
};
#endif

在上面的代码中,当我没有在Test.h添加Analyzer时,一切正常。 但是添加后显示以下链接器错误。

1>Test2.obj : error LNK2005: "int counternamespace::lowerbound" (?lowerbound@counternamespace@@3HA) already defined in Analyzer.obj
2>Test2.obj : error LNK2005: "int counternamespace::upperbound" (?upperbound@counternamespace@@3HA) already defined in Analyzer.obj

我添加了#ifndef / #endif 那我在哪里做错了? 有人可以让我知道吗?

是的,阿洛克说的没错。 您大概拥有Analyser.cpp和Test2.cpp,它们都是不同的编译单元。 你打电话时

g++ Analyser.cpp Test2.cpp

编译器实际上分别制作了Analyser.obj和Test2.obj并将它们链接在一起。 当编译器尝试将Analyser.obj和Test2.obj链接在一起时,它意识到Test2.obj中的两个变量也存在于Analyser.obj中。

#define指令不工作,因为它们只存在于一个单一的编译单元,所以general.h中在Analyser.obj和Test2.obj包括在内。

为避免此类重复, 解决方案将函数包装您的名称空间变量 它是这样的:

内部General.h

#ifndef GENERAL
#define GENERAL
namespace counternamespace{
    int& upperbound();
    int& lowerbound();
}
#endif

在General.cpp内部

#include "General.h"
namespace counternamespace{
  int& upperbound(){static int local; return local;}
  int& lowerbound(){static int local; return local;}
}

所以你现在可以说

counternamespace::upperbound()=3;
counternamespace::lowerbound()=1;

它的含义与您所说的相同

counternamespace::upperbound = 3;
counternamespace::lowerbound = 1;

不用担心,编译器将优化函数调用,因此也没有开销。

您不应在头文件中定义任何变量。
当您在其他文件中包含头文件时,将在每个转换单元中创建变量的副本,从而违反了一个定义规则,并导致链接错误。

Inside General.h

#ifndef GENERAL
#define GENERAL
namespace counternamespace{
    extern int upperbound;
    extern int lowerbound;
}
#endif

Inside General.cpp

#include"General.h"
using namespace counternamespace ;
int counternamepace::upperbound = 12;
int counternamepace::lowerbound = 12;

然后做任何需要的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM