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.
Related
ConsoleApplication1.cpp
#include <iostream>
#include "Test.h"
#include "Head1.h"
int main()
{
std::cout << "Hello World!\n";
}
Test.h
#pragma once
int AAA = 1;
Head1.h
#pragma once
#include "Test.h"
Head2.h
#pragma once
class Head2C
{
public:
void Print();
};
Head2.cpp
#include "Head2.h"
#include "Head1.h"
#include <iostream>
using namespace std;
void Head2C::Print()
{
cout << "Head2::Print() " << endl;
}
Why #pragma once can't work for this sample code?
The linker error : error LNK2005: "int AAA" (?AAA##3HA) already defined in ConsoleApplication1.obj
Every non-constant variable should be defined only once in the entire program. #pragma once only ensures that it is defined once for each translation unit (cpp file). With two translation units, you are defining the variable twice in the entire program.
Make AAA constant or move the definition into a cpp file.
I cannot compile my C++ program and I don't understand why.
Here's a simple representation of what is throwing errors:
hello/hello.cpp
#include "hello.h"
namespace MyHelloNS {
MyHelloClass::MyHelloClass() {
MyHelloVAR1 = "hi";
MyHelloVAR2 = "dog";
}
}
hello/hello.h
#pragma once
#include <string>
using namespace std;
namespace MyHelloNS {
extern string MyHelloVAR1;
extern string MyHelloVAR2;
class MyHelloClass;
}
class MyHelloNS::MyHelloClass {
public:
MyHelloClass();
};
main.cpp
#include "hello/hello.h"
int main() {
MyHelloNS::MyHelloClass hi1;
}
I get two kinds of errors:
unresolved external symbol in hello.obj
What's wrong?
Add this to main.cpp (or hello.cpp)
namespace MyHelloNS {
string MyHelloVAR1;
string MyHelloVAR2;
}
This question has nothing to do with namespaces, you just aren't following the correct procedure to define a global variable.
I have this code:
#ifndef AI_H
#define AI_H
void BuildTree(Board b);
int getMove();
void acceptMove(int);
#endif
and the cpp file:
#include "AI.h"
#include "Board.h"
void BuildTree(Board b)
{
}
int getMove()
{
return 0;
}
void acceptMove(int)
{
}
I am getting an error because of the paramater Board b in the header file.
the error is:
Error 1 error C2065: 'Board' : undeclared identifier
why is it not accepting an object?? I want the function to receive an object by value, not reference.
Just include Board.h in ai.h:
#ifndef AI_H
#define AI_H
#include "Board.h"
void BuildTree(Board b);
int getMove();
void acceptMove(int);
#endif
The compiler is complaining about Board: it does not know what is it. You must define (not only declare) it to be able to use an object of that type (e.g. taking it as parameter).
You can solve your issue by #includeing the header file defining Board :
#include "Board.h"
Include Board.h in your first file, AI.h
So I am confused. I am getting a redefinition error when trying to implement a method previously declared in a header file. I added include guards to the header and still got the same error. If someone could explain to me what I am not seeing, that would be fantastic.
In file included from main.cpp:2:
./thing.cpp:7:12: error: redefinition of 'method'
int Thing::method(void)
^
./thing.hpp:12:6: note: previous definition is here
int method(void) {};
^
--EDIT--
I am now getting the following:
duplicate symbol __ZN5Thing6methodEv in:
main.o
thing.o ld: 1 duplicate symbol for architecture x86_64
thing.hpp:
#ifndef THING_H
#define THING_H
class Thing {
public:
int a;
int b;
char c;
int method(void) {};
Thing(int anA, int aB, char aC): a(anA), b(aB), c(aC) {};
};
#endif
thing.cpp
#include <iostream>
#include <stdio.h>
#include "thing.hpp"
using namespace std;
int Thing::method(void)
{
return 5;
}
main.cpp
#include <iostream>
#include "thing.cpp"
using namespace std;
Thing* thing = new Thing(5,5,'c');
int main(int argc, char ** argv)
{
cout << thing->method() <<endl;
}
In your header file you have:
int method(void) {};
That's an inline definition, not a declaration. The {} is actually providing the (albeit empty) function body to the compiler. Remove the {} if you want to define the function in another file.
Additionally, you have #include "thing.cpp" rather than #include "thing.hpp" at the top of your main.cpp file.
In main.cpp you need to change:
#include "thing.cpp"
to:
#include "thing.hpp"
I was playing around with namespaces when I encountered a lnk2005 error. I can't figure out how to get around the error. Here's the error:
1>Source.obj : error LNK2005: "int Chart::Bars::d" (?d#Bars#Chart##3HA) already defined in Chart.obj
1>Source.obj : error LNK2005: "class foo Chart::l" (?l#Chart##3Vfoo##A) already defined in Chart.obj
1>Source.obj : error LNK2005: "int Chart::t" (?t#Chart##3HA) already defined in Chart.obj
1>C:\Users\bnm\dev\examples\play\nmspca\Debug\nmspca.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.49
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Here's the code...
Chart.h
#pragma once
#include "foo.h"
namespace Chart
{
int t;
foo l;
namespace Bars
{
int d;
}
}
Foo.h
#pragma once
class foo
{
public:
int ss;
char* h;
};
Chart.cpp
#include "Chart.h"
using namespace Chart;
int main ()
{
l.h = "g";
}
Source.cpp
#include "Chart.h"
using namespace Chart;
int test()
{
l.ss = 0;
return l.ss;
}
When the #include "Chart.h" from Source.cpp is removed the problems goes away. However, Source.cpp needs #include "Chart.h" for the namespace definition.
What's the correct way to express that "namespace Chart" is needed in both Chart.cpp and Source.cpp so that everything compiles?
If you define any objects in a header file and include that header file in multiple translation units, those objects are now defined multiple times. This is the problem you're having. The declarations of t, l, and d introduce objects and you have done so in a header file.
The proper method for supporting namespace scope variables is to declare them as extern in the header file. This makes them declarations only and not definitions. Then, in a single implementation file, define them.
Change Chart.h to:
#pragma once
#include "foo.h"
namespace Chart
{
extern int t;
extern foo l;
namespace Bars
{
extern int d;
}
}
Then in an implementation file, perhaps Chart.cpp, do:
int Chart::t;
foo Chart::t;
int Chart::Bars::d;
Everywhere you're including Chart.h, you're effectively dropping variables t, l, and d into those objects. Declare them as extern, then define them in Chart.cpp
I've had the exact same problem and I found a workarroud.
chart.h becomes:
#pragma once
#include "foo.h"
class Chart{
static int t;
static foo l;
class Bars
{
static int d;
};
};
and define the variables in chart.cpp
int Chart::t;
foo Chart::l;
int Chart::Bars::d;
Ugly, I know, but at least the syntax is the same wherever you need to use the vars.
This way only ONE .obj file is created containing the variables which prevents the multiple definition erros.
I haven't tried if you can declare a static variable on a namespace which could solve the problem.
Edit:
P.S. this solution gives some weird errors on msvc, as if every time it is included, sections of the code reference differente variables
Tested on my own program the static-inside-namespace and it seems to work.
Example.h:
namespace sdl{
static SDL_Surface* screen;
static int xres = 640;
static int yres = 480;
static int bpp = 32;
static int flags = SDL_ASYNCBLIT;
};