只是一个非常小的程序来测试如何使用命名空间。我把它分成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
如果你知道怎么做,请帮助我。非常感谢。
答案 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 中定义了两个变量a
和b
,然后头文件包含在两个源文件中。这违反了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
,然后在其中一个源文件中定义。