I would like to avoid re-definition from two different include files as follows:
File ABC.h
extern int v=1;
File foo.h
#include "ABC.h"
class Foo
#ifdef BLA
: public ABC
#endif
{
...
};
File bar.h
extern int v=3;
Main:
#define BLA
#include <foo.h>
#include <bar.h>
Basically foo is a class written by me, and bar is a third-party library. But it doesn't seem to work. How should I solve the problem?
Sorry, it's a bit hard to describe, the example is kind of bad as the conflicted parts are actually not variables, but something like #define and wrapped in big blocks of code (error message is: "multiple definition of `__vector_17'"). Is there a way to solve it without using a namespace?
Using a namespace you can solve this problem:
namespace foo
{
int val =1;
}
namespace bar
{
int val =3;
}
using namespace foo;
int x = val; //Now x will be assigned with 1
A namespace is what you need:
namespace foo
{
int v =100;
}
namespace bar
{
int v =500;
}
Related
I've got two files, list.cpp and Header.h. Segments of the files are below. I know that if the header file is for a class, it is setup different. E.g.
class MyClass
{
public:
void foo();
int bar;
};
However, since I'm not really working with a class here (correct me if I'm wrong), am I not able to declare things under public: and private like below?
Also, if I were to place the global variable rescan in the header file as a member variable, below the function definitions, only the main function can see the variable. Why is it not within the scope of the other functions?
list.cpp:
#include <boost/algorithm/string.hpp>
#include <vector>
using namespace std;
vector<int> results;
bool rescan;
int main()
{
vector<vector<string>> list;
int success = readFile(list);
vector<vector<string>> bad = findMe(list);
system("pause");
return 0;
}
vector<vector<string>> findMe(vector<vector<string>> find)
{
rescan = true;
}
Header.h:
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <string>
#include <vector>
std::vector<std::vector<std::string>> findMe(std::vector<std::vector<std::string>>);
#endif
EDIT: I tried this in my header file:
public:
bool rescan;
But I got "syntax error: 'public'
If you want your global to be visible in other translation units (TU) (other files), you have to declare them extern in those other TUs:
Header.h:
// Include guard omitted
extern bool rescan; // Declaration
file.cpp
#include "Header.h"
bool rescan = false; // Definition
// ...
file2.cpp
#include "Header.h" // To see extern bool rescan;
void foo()
{
rescan = true;
}
// ...
Consider this code.
//header.h
int x;
//otherSource.cpp
#include "header.h"
//main.cpp
#include "header.h"
...
int main()
{
}
In this case compiler erred with the message. "fatal error LNK1169: one or more multiply defined symbols found"
but when I add static before x, it compiles without errors.
And here is the second case.
//header.h
class A
{
public:
void f(){}
static int a;
};
int A::a = 0;
/otherSource.cpp
#include "header.h"
//main.cpp
#include "header.h"
...
int main()
{
}
In this case compiler again erred with multiple declaration.
Can anybody explain me the behavior we static variables in classes and in global declarations?? Thanks in advance.
The issue with the static member variable is that you have the definition occur in the header file. If you #include the file in multiple source files, you have multiple definitions of the static member variable.
To fix this, the header file should consist only of this:
#ifndef HEADER_H
#define HEADER_H
// In the header file
class A
{
public:
void f(){}
static int a;
};
#endif
The definition of the static variable a should be in one and only one module. The obvious place for this is in your main.cpp.
#include "header.h"
int A::a = 0; // defined here
int main()
{
}
Declare x as extern in header.h to tell the compiler that x will be defined somewhere else:
extern int x;
Then define x once in the source file which you think is most fitting.
For example in otherSource.cpp:
int x = some_initial_value;
Hi i just created a sample class and using it in main but i am getting already defined error.
sample.h
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
#endif
sample.cpp
#include "sample.h"
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
main.cpp
#include <iostream>
#include "sample.h"
using namespace std;
int main(void)
{
int test = count;
return 0;
}
Link error:
main.obj : error LNK2005: "int count" (?count##3HA) already defined in sample.obj
if u see above class i am using #ifndef and #define, actually there things will declare data once thought we include in many places.could some one explain me clearly why its giving that link error.
Remember that #include literally means "add the contents of this file here".
Include guards only protects against a file's content being included more than once per file it's included in.
When the preprocessor has done its preprocessing, this is what your compiler sees:
sample.cpp
[iostream contents here...]
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
main.cpp
[iostream contents here...]
using namespace std;
int count = 10;
class sample
{
public:
sample();
int Get();
private:
int i;
};
using namespace std;
int main(void)
{
int test = count;
return 0;
}
As you can see, there are two definitions of count, one in each file (formally, "translation unit").
The solution is to have a declaration of the variable in "sample.h"
extern int count;
and have the one and only definition in sample.cpp:
int count = 10;
(And you should not put using namespace std; in a header.)
To make a global variable like that visible everywhere:
blah.h
extern int count;
blah.cpp
int count(10);
Include guards only guard against including the same header file multiple times, not against multiple definitions. You should move your variable in a cpp file in order to not violate the ODR, or use internal linkage or declare it external and define it somewhere once. There are multiple solutions depending on the use of that variable.
Notice that I'm ignoring the fact that you probably meant int sample::Get() in the sample.cpp file
#include "sample.h"
sample::sample()
{
cout<<"hello two";
}
int sample::sample() // ??
{
return 10;
}
You have either to declare variable count as having internal linkage as for example
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
namespace
{
int count = 10;
}
//...
#endif
(the above internal declaration valid in C++ 2011) or
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
static int count = 10;
//...
#endif
Or to declare it as having external linkage but define it only once in some module. Fpr example
#ifndef __sample__
#define __sample__
#include<iostream>
using namespace std;
extern int count;
//...
#endif
#include "sample.h"
int count = 10;
sample::sample()
{
cout<<"hello two";
}
int sample::sample()
{
return 10;
}
Otherwise the compiler will issue an error that variable count is defined more than once that is that more than one compilation unit (in this case sample.cpp and main.cpp) contain the variable definition.
I want to modify object "t1" of the class "abc" in "update" function which is defined in different file(temp2.cpp) than where "t1" is defined(temp1.cpp). I tried to use extern but that resulted in error. Please suggest nice way of doing this.
temp1.ccp
#include<iostream>
#include "test2.cpp"
using namespace std;
class abc{
public:
int x;
char y;
void printxy(){
cout<<x<<y<<endl;
}
};
abc t1;
int main(){
update();
return 0;
}
test2.cpp
extern abc t1;
void update(){
t1.x=5;
t1.y='A';
t1.printxy();
};
In file included from test.cpp:2:0: test2.cpp:1:8: error: `abc' does not name a type
extern abc t1;
^
test2.cpp: In function `void update()':
test2.cpp:3:2: error: `t1' was not declared in this scope t1.x=5;
You include test2.cpp before the declaration of class abc: the included file just gets expanded at the location where the #include occurs. You might want to use your code with the compiler's -E option to see how the file looks after preprocessing (in which case you probably also want to omit the #include <iostream> as it will produce lots of output).
In general, it isn't a good idea to include .cpp files. Did you mean the declarations to be a header file (e.g., test2.h) and include that at the type of test2.cpp? In that case the order of the declaration would be OK.
Finally I got it. Thanks for your comments :)
class.h
class abc{
public:
int x;
char y;
void printxy(){
std::cout<< x << y <<std::endl;
};
};
func.h
extern abc t1;
void update(){
t1.x=5;
t1.y='A';
t1.printxy();
};
main file
#include <iostream>
#include "class.h"
#include "func.h"
abc t1;
int main(){
update();
return 0;
}
Output
5A
Consider the following example. It consists of two header files, declaring two different namespaces:
// a1.h
#pragma once
#include "a2.h"
namespace a1
{
const int x = 10;
typedef a2::C B;
}
and the second one is
// a2.h
#pragma once
#include "a1.h"
namespace a2 {
class C {
public:
int say() {
return a1::x;
}
};
}
And a single source file, main.cpp:
#include <iostream>
#include "a1.h"
#include "a2.h"
int main()
{
a2::C c;
std::cout << c.say() << std::endl;
}
This way it doesn't compile (tried GCC and MSVC). The error is that a1 namespaces is not declared (C2653 on Windows). If you change include order in main.cpp this way:
#include "a2.h"
#include "a1.h"
you get a symmetric error message, i.e. a2 namespace is not declared.
What's the problem?
You need to use a forward declaration in your header files because you have a circular reference. Something like this:
// a1.h
#pragma once
namespace a2 {
class C;
}
namespace a1
{
const int x = 10;
typedef a2::C B;
}
Just a guess, but your include reference is circular. Meaning the compiler can't figure out which header to compile first. a1 references a2 which references a1.
If possible, merge/reorganize the files so that there is a non-circular chain of includes.
Hope that helps!
When you include a1.h first, it immediately tries to include a2.h before declaring anything
a2.h references something in namespace a1 that hasn't been declared yet
When you include a2.h first, it immediately tries to include a1.h before declaring anything
a1.h references something in namespace a2 that hasn't been declared yet
Removing the typedef from a1.h, which you aren't using, and not including a2.h removes the cycle.
Or as by the other commenter, forward declare class C.
// a1.h
#pragma once
//#include "a2.h"
namespace a1
{
const int x = 10;
// typedef a2::C B;
}