I declare a Algebra.h file which holds the declaration of an add() function:
#ifndef Algebra_
#define Algebra_
namespace Algebra{
int add(int x, int y);
}
#endif
Then I implement add() as:
Algebra.cpp
#include "Algebra.h"
namespace Algebra{
int add(int x, int y){
return x+y;
}
}
Then I have classes A and B, which include Algebra.h:
B.h
#ifndef B_
#define B_
#include "Algebra.h"
#include <iostream>
class B{
public:
void func(int x, int y);
};
#endif
B.cpp
#include "B.h"
void B::func(int x, int y){
int val = Algebra::add(x,y);
std::cout << "B : "<< val << std::endl;
}
A.h
#ifndef A_
#define A_
#include <iostream>
#include "Algebra.h"
#include "B.h"
class A{
public:
void func(int x, int y);
};
#endif
A.cpp
#include "A.h"
void A::func(int x, int y){
int val = Algebra::add(x,y);
std::cout << "A : " << val << std::endl;
}
main.cpp
#include "A.h"
#include "B.h"
#include "Algebra.h"
int main(){
A a;
B b;
a.func(3,4);
b.func(3,4);
int val = Algebra::add(3,4);
std::cout << "main : " << val << std::endl;
}
I tried compilation using
g++ A.cpp B.cpp main.cpp -o bin
g++ A.cpp B.cpp Algebra.cpp main.cpp -o bin
I get this error:
/tmp/ccBXhev4.o: In function 'Algebra::add(int, int)':
main.cpp:(.text+0x0): multiple definition of 'Algebra::add(int, int)'
/tmp/ccfaCF5H.o:A.cpp:(.text+0x0): first defined here collect2: error:
ld returned 1 exit status
I even tried inlining the add() function in Algebra, but still get the error. Also I don't want to make Algebra be a class.
Why am I getting a multiple definition error even though I am adding the Algebra header file, and it does not define but only declare?
Related
I have the following four files a.hpp, b.hpp, b.cpp and main.cpp in Ubuntu 16.04LTS that mimic my original files.
a.hpp
#ifndef A_H
#define A_H
#include <iostream>
namespace Utility{
typedef struct _structure{
int v;
int w;
}aStructure;
void foo(){
std::cout << "foo" << std::endl;
}
void goo(){
foo();
}
}
#endif
b.hpp
#ifndef B_H
#define B_H
#include <iostream>
#include "a.hpp"
class bCls{
private:
int x;
public:
void moo(Utility::aStructure s);
};
#endif
b.cpp
#include <iostream>
#include "a.hpp"
#include "b.hpp"
void bCls::moo(Utility::aStructure s){
std::cout << "moo" << std::endl;
}
main.cpp
#include <iostream>
#include "a.hpp"
#include "b.hpp"
int main(){
Utility::aStructure s;
bCls u;
u.moo(s);
return 0;
}
When I try to compile using g++ -std=c++11 b.cpp main.cpp the following error message is thrown:
/tmp/ccwvPrRr.o: In function `Utility::foo()':
main.cpp:(.text+0x0): multiple definition of `Utility::foo()'
/tmp/ccCVJOoH.o:b.cpp:(.text+0x0): first defined here
/tmp/ccwvPrRr.o: In function `Utility::goo()':
main.cpp:(.text+0x23): multiple definition of `Utility::goo()'
/tmp/ccCVJOoH.o:b.cpp:(.text+0x23): first defined here
collect2: error: ld returned 1 exit status
My search resulted in Why am I getting multiple definition error when header included?. But one difference in my code is that a.hpp is required in each of b.hpp, b.cpp and main.cpp.
I am very curious to know what I am doing wrong and the best approach to code in this case and corresponding pitfalls.
The thing is that I am trying to have a global constant variable for all the .hand .cpp files, but when I do this I got the error:
array bound is not an integer constant before ‘]’ token
I do not understand this because Z is a constant. When I do this with just one file it works. What am I doing wrong?
Number.h
#include <iostream>
extern const int Z;
a.cpp
#include <iostream>
#include "b.h"
#include "c.h"
#include "Number.h"
using namespace std;
int main() {
const int Z = 5;
b Objeto1;
c Objeto2;
double H[Z][Z];
Objeto1.Algo(H);
Objeto2.Imprimir(H);
return 0;
}
b.h
#include <iostream>
#include "Number.h"
class b {
public:
void Algo(double[Z][Z]);
};
b.cpp
#include <iostream>
#include "b.h"
#include "Number.h"
using namespace std;
void b::Algo(double H[Z][Z]) {
for(int a = 0; a < Z; a++) {
for(int b = 0; b < Z; b++) {
H[a][b] = Z;
cout << H[a][b] << endl;
}
}
}
c.h
#include <iostream>
#include "Number.h"
class c {
public:
void Imprimir(double H[Z][Z]);
};
c.cpp
#include <iostream>
#include "c.h"
#include "Number.h"
using namespace std;
void c::Imprimir(double V[Z][Z]) {
cout << "dfs" << endl;
}
I know that the code does not make any sense, but I am just trying to understand how I could have a constant for all the files. I really appreciate your help.
Use of
extern const int Z;
is perfectly fine. However, you can't use Z to define an array. Hence, use of Z in the following line, and similar other lines, is incorrect.
class b{
public:
void Algo(double[Z][Z]);
};
The size of arrays must be known at compiler time. With the extern declaration you have provided, that is not true.
The use of extern const is justified only when you wish to define the value at run time and expect the value to not change until the program ends.
If you simply wish to use it as a token for defining arrays, remove the extern and set its value also. Use:
const int Z = 5;
I have 3 files namely "main.cpp", "testclass.cpp" and "testclass.h". I compile the files by calling:
g++ testclass.cpp main.cpp
main.cpp
#include <iostream>
#include "testclass.hpp"
int main()
{
testclass foo(56);
std::cout << "Object in cpp\t" << numberobject.getNumber() << "\n";
return 0;
}
testclass header
#ifndef TESTCLASS_H
#define TESTCLASS_H
class testclass
{
private:
int number;
public:
testclass();
testclass(int);
int getNumber();
};
#endif //TESTCLASS_H
testclass.cpp
#include "testclass.hpp"
testclass::testclass()
{
}
testclass::testclass(int number)
{
this->number = number;
}
int testclass::getNumber()
{
return number;
}
There will be a compile error
testclass.cpp:7:1: error: prototype for ‘testclass::testclass(int)’ does not match any in class ‘testclass’
testclass::testclass(int number)
^
testclass.h:4:7: error: candidates are: testclass::testclass(const testclass&)
class testclass
^
testclass.cpp:3:1: error: testclass::testclass()
testclass::testclass()
^
However, if I change the "testclass.h" to "testclass.hpp" and also change all #include statment from #include "testclass.h" to #include "testclass.hpp", it works well.
Why I can't compile the .h file? And is there anyway to compile with .h file?
Finally, I found that there is a strange 'testobject.h.gch" file under the same directory. It works fine after I remove it.
I want to test defining a const in a header and use it in functions, then call it. However I get the error, I added include guards which doesn't help. Error is: LNK1169: One or more defined multiply symbols found. How can i do it in a nother way? Is declaring const in .h and defining this const in .cpp and then including this .cpp in all other .cpps the only solution?
Header
#ifndef STORY
#define STORY
const int x = 4;
#endif
.cpp
#include <iostream>
#include "8-04.h"
void func1()
{
int w = x;
std::cout << "func1 " << w << std::endl;
}
.cpp
#include <iostream>
#include "8-04.h"
void func2()
{
int z = x;
std::cout << "func2 " << z << std::endl;
}
main
#include <iostream>
#include "8-04.h"
#include "8-04first.cpp"
#include "8-04second.cpp"
using namespace std;
int main()
{
func1();
func2();
}
The problem is that each .cpp includes the .h. This means that each .o contains a const int x. When the linker links these together, you get multiple definitions.
The solution is to modify the .h
#ifndef STORY
#define STORY
extern const int x; //Do not initialise
#endif
and in a single .cpp:
const int x=4
Edit:
I didnt even see the #include <file.cpp> business. Don't do that. Its horrible.
This should be like :
header.h:
#ifndef STORY
#define STORY
const int x = 4;
void func1();
void func2();
#endif
fun1.cpp
#include <iostream>
#include "header.h"
void func1()
{
int w = x;
std::cout << "func1 " << w << std::endl;
}
fun2.cpp
#include <iostream>
#include "header.h"
void func2()
{
int z = x;
std::cout << "func2 " << z << std::endl;
}
main.cpp
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
func1();
func2();
}
You can not include ".cpp"
It can be done such as :
header.h:
#ifndef STORY
#define STORY
const int x = 4;
void func1();
void func2();
#endif
fun1.cpp
#include <iostream>
#include "header.h"
using namespace std;
void func1()
{
int w = x;
cout << "func1 value of w = " << w << "\n";
}
fun2.cpp
#include <iostream>
#include "header.h"
using namespace std;
void func2()
{
int z = x;
cout << "func2 value of z = " << z << "\n";
}
main.cpp
#include <iostream>
#include "header.h"
int main()
{
func1();
func2();
}
".cpp" file cannot be included in main source file.
in foo.h:
#ifndef FOO_H
#define FOO_H
enum Rat
{
A,
B
};
class Foo
{
public:
template<Rat r>
int aMemberFunc(int, int, int);
};
#endif
in foo.cpp:
#include "foo.h"
namespace {
template<Rat r>
int helper(int a, int b)
{
return a+b*((int) r);
}
}
template<Rat r>
int Foo::aMemberFunc(int a, int b, int c)
{
return a + helper<r>(b,c);
}
in main.cpp:
#include "foo.h"
#include <iostream>
using namespace std;
int main(void)
{
Foo test;
cout << test.aMemberFunc<B>(1,2,3) << endl;
}
I compile with g++ main.cpp foo.cpp and I get:
main.cpp:(.text+0x88): undefined reference to `int Foo::aMemberFunc<(Rat)1>(int, int, int)'
collect2: ld returned 1 exit status
I would prefer not to move stuff to the header because that brings along the helper and a lot of baggage, I tried to add a file fooimpl.cpp:
#include "foo.h"
#include "foo.cpp"
template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);
and then compile with g++ fooimpl.cpp main.cpp foo.cpp
This was per the suggestion of Dietmar (thanks!) but as soon as I add a function void rand(); in the header of foo.h and void rand() {} in foo.cpp the above trick yields this error:
foo.cpp:(.text+0x0): multiple definition of `Foo::rand()'
/tmp/ccoCtGMk.o:fooimpl.cpp:(.text+0x0): first defined here
how do i work around this?
You need to instantiate your function, not specialize it:
#include "foo.h"
#include "foo.cpp"
template int Foo::aMemberFunc<A>(int,int,int);
template int Foo::aMemberFunc<B>(int,int,int);