命名空间未定义或重新定义,为什么?

时间:2011-08-17 21:47:44

标签: c++

只是一个非常小的程序来测试如何使用命名空间。我把它分成3个文件,因为在大型产品中,ns.h是命名空间接口,ns.cpp是实现。我不能将所有这些东西都放在一个文件中。

以下是代码:

//ns.h
#ifndef MY_H
#define MY_H
namespace my
{
    int a=1;
    int b=0;
    void test();
}
#endif

//ns.cpp
#include <iostream>
#include "ns.h"

using namespace my;
//my::a=1;
//my::b=0;
void my::test()
{
    std::cout<<a<<std::endl;
}

//testns.cpp
#include <iostream>
#include "ns.h"
int main()
{
    std::cout<<my::b<<std::endl;
    my::test();
}

如果我保留上面的代码,编译就会得到:

testns.obj : error LNK2005: "int my::b" (?b@my@@3HA) already defined in ns.obj
testns.obj : error LNK2005: "int my::a" (?a@my@@3HA) already defined in ns.obj

如果我对语句#include“ns.h”发表评论,我将收到未定义的错误。

D:\mfc\testns.cpp(5) : error C2653: 'my' : is not a class or namespace name
D:\mfc\testns.cpp(5) : error C2065: 'b' : undeclared identifier
D:\mfc\testns.cpp(6) : error C2653: 'my' : is not a class or namespace name
D:\mfc\testns.cpp(6) : error C2065: 'test' : undeclared identifier

如果你知道怎么做,请帮助我。非常感谢。

3 个答案:

答案 0 :(得分:2)

标题用于声明,而不是定义。这与命名空间问题无关。

//ns.h
#ifndef MY_H
#define MY_H
namespace my
{
    extern int a, b; // declared, not defined thanks to 'extern'.
    void test();
}
#endif

//ns.cpp
#include <iostream>
#include "ns.h"

int my::a=1; // now we provide the actual definitions.
int my::b=0;
void my::test()
{
    std::cout << my::a << std::endl;
}

//testns.cpp
#include <iostream>
#include "ns.h"
int main()
{
    std::cout << my::b << std::endl;
    my::test();
}

答案 1 :(得分:2)

您已在 ns.h 中定义了两个变量ab,然后头文件包含在两个源文件中。这违反了one definition rule,因为现在在包含 ns.h 的翻译单元中定义了变量。

您需要做的是在标题中声明变量,并在单个源文件中定义

要解决此问题,请将 ns.h 更改为

#ifndef MY_H
#define MY_H
namespace my
{
    extern int a;
    extern int b;
    void test();
}
#endif

ns.cpp

#include <iostream>
#include "ns.h"

using namespace my;

int my::a=1;

int my::b=0;

void my::test()
{
    std::cout<<a<<std::endl;
}

答案 2 :(得分:1)

在头文件中定义变量并非标准做法;每次#include标题时都会重新定义它们,从而导致您看到的链接器错误。

如果你需要在源文件之间共享变量(并且这很少有很好的理由),那么你应该在头文件中将它们声明为extern,然后在其中一个源文件中定义