简体   繁体   中英

namespace either undefined or redefined, why?

just a very small program to test how to use the namespace. I divide it into 3 files, since in large product, ns.h is the namespace interface and ns.cpp is the implementation. I cannot put all these stuff into one file.

Here is the code:

//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();
}

If I keep the above code, and compile will get:

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

If I comment the statement #include "ns.h" I will get undefined error.

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

Kindly help me if you know how to do this. Thanks a lot.

Headers are for declarations, not definitions. That's nothing to do with the namespace problem.

//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();
}

You've defined the two variables a and b in ns.h and then the header file is being included in two source files. This violates the one definition rule as the variables are now defined in both the translation units that are including ns.h .

What you need to do is declare variables in the header and define them in a single source file.

To fix the problem, change ns.h to

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

In 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;
}

It's not standard practice to define variables in a header file; they are re-defined every time you #include the header, leading to the linker errors that you are seeing.

If you need to share variables between source files (and there's very few good reasons for this), then you should declare them as extern in the header file, and then define them in one of your source files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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