0

General.h 内部

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

Analyzer.h 内部

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

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

内部测试.h

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

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

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

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。那我在哪里做错了?谁能告诉我?

4

3 回答 3

2

是的,阿洛克是对的。您大概有 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;

别担心,编译器会优化掉函数调用,所以也没有开销。

于 2012-12-31T10:38:00.287 回答
1

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

于 2012-12-31T10:27:03.943 回答
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;

然后做任何需要的事情。

于 2013-01-01T17:49:57.307 回答