I have made the following C++ program which is made up of 3 files:
The thing.h file
#ifndef THING_H
#define THING_H
class thing{
double something;
public:
thing(double);
~thing();
double getthing();
void setthing(double);
void print();
};
#endif
The thing.cpp file
#include <iostream>
#include "thing.h"
thing::thing(double d){
something=d;
}
thing::~thing(){
std::cout << "Destructed" << std::endl;
}
double thing::getthing(){
return something;
}
void thing::setthing(double d){
something = d;
}
void thing::print(){
std::cout <<"The someting is " << something << std::endl;
}
The main file
#include <iostream>
#include "thing.h"
int main(){
thing t1(5.5);
t1.print();
t1.setthing(7.);
double d=t1.getthing();
std::cout << d << std::endl;
system("pause");
return 0;
}
I had made this program previously all in one file and it ran perfectly but when I try split it into seperate files to create a header I get a linker error, here is the errors I get when I try run it from the main file:
[Linker error] undefined reference to `thing::thing(double)'
[Linker error] undefined reference to `thing::print()'
[Linker error] undefined reference to `thing::setthing(double)'
[Linker error] undefined reference to `thing::getthing()'
[Linker error] undefined reference to `thing::~thing()'
[Linker error] undefined reference to `thing::~thing()'
ld returned 1 exit status
From the above errors it seems asthough the main file doesnt recognise the functions inside the header, how do I fix this please?
In slightly less pedantic terms:
Your header file thing.h declares "what class thing should look like", but not its implementation, which is in the source file thing.cpp. By including the header in your main file (we'll call it main.cpp), the compiler is informed of the description of class thing when compiling the file, but not how class thing actually works. When the linker tries to create the entire program, it then complains that the implementation (thing::print() and friends) cannot be found.
The solution is to link all the files together when creating the actual program binary. When using the g++ frontend, you can do this by specifying all the source files together on the command line. For example:
g++ -o main thing.cpp main.cpp
will create the main program called "main".
It seems you are not linking thing.cpp into your "project".
If you are compiling using gcc:
g++ thing.cpp -o thing.o
g++ main.cpp -o main.o
g++ main.o thing.o -o my-best-application-ever
How to add the file to your project depends on the compiler/IDE/build-system you are using.
#sheu is right.. But you don't have to do anything if you just include thing.cpp in your main.cpp
Since you're already including thing.h in thing.cpp everything will work just fine if you include thing.cpp
Compiler knows about declarations of functions, but nothing about definitions. You need to say them where they are. The easiest way to do that is to create 'project' and add all files to it. Then compiler knows where to search all files.
Put some code in thing.cpp which let you know that it is being compiled i.e.
error ...
apparently it is not being compiled and linked...
Related
hope you guys are doing well. I am just getting linker error in C++ , I don't know why? Everything is correct....
Check below testing.h file
#ifndef __MYClass__
#define __MYClass__
#include<iostream>
using namespace std;
class Abc {
private:
int a;
public:
void input();
void display();
};
#endif
and here's implementation of these functions in Functions.cpp file.
#include"testing.h"
void Abc::input() {
cout<<"Enter any value : ";
cin>>a;
}
void Abc::display() {
cout<<"You Entered : "<<a;
}
And now, in main.cpp
#include<iostream>
#include"testing.h"
using namespace std;
int main() {
Abc obj;
obj.input();
obj.display();
return 0;
}
All files are compiled successfully.
In main.cpp Linker says....
g++ -Wall -o "main" "main.cpp" (in directory: /home/Welcome/C++ Practices/testingLinux)
/usr/bin/ld: /tmp/ccYI9LAy.o: in function main': main.cpp:(.text+0x10): undefined reference to Abc::input()'
/usr/bin/ld: main.cpp:(.text+0x1c): undefined reference to `Abc::display()'
collect2: error: ld returned 1 exit status
Compilation failed.
I'm using built-in linux compiler...
There are multiple ways you can fix this but before that please read up on Translation Unit.
Coming to your problem.
When you write
g++ -Wall -o main main.cpp
The compiler will pick up main.cpp for compilation and expand testing.h that includes the declaration for class ABC and with this header file it can determine what is the size of ABC and be able to generate instructions reserving space for obj on the stack. It can't see the definition for input() and display() hence defers that task to the linker. Note that testing.cpp is not in the picture at all since the compiler doesn't know that the implementation of ABC is in testing.cpp. Now when the linker tries to resolve the symbols input() it fails to find the definition for it and throws the error
undefined reference to Abc::input()
So, to fix this you can tell explicitly upfront that it also needs to take in testing.cpp while compiling main.cpp by
g++ -o main main.cpp testing.cpp
Another way is to create a dynamic library out of testing.h and testing.cpp
g++ -shared -fPIC testing.cpp -o libtest
and then link it against main.cpp
g++ -o main main.cpp -I. -L. libtest
What this does is that the compiler still can't figure out the definition of input() and display() but the linker can since now the library containing the definitions is provided to it.
You are not compiling Functions.cpp file.
This should fix your issue:
g++ main.cpp Functions.cpp
I can't seem to get the errors to go away. The errors are below. I have looked on Google Search and still I can't figure it out. It is not like I am new to C++, but I have not fooled around with it in a while.
The weird thing is it worked with g++ on Windows...
Errors using:
g++ main.cpp
Output:
/tmp/ccJL2ZHE.o: In function main': \ main.cpp:(.text+0x11): undefined reference to Help::Help()'
main.cpp:(.text+0x1d): undefined reference to Help::sayName()' \ main.cpp:(.text+0x2e): undefined reference to Help::~Help()'
main.cpp:(.text+0x46): undefined reference to `Help::~Help()'
collect2: ld returned 1 exit status
File main.cpp
#include <iostream>
#include "Help.h"
using namespace std;
int main () {
Help h;
h.sayName();
// ***
// ***
// ***
return 0;
}
File Help.h
#ifndef HELP_H
#define HELP_H
class Help {
public:
Help();
~Help();
void sayName();
protected:
private:
};
#endif // HELP_H
File Help.cpp
#include <iostream>
#include "Help.h"
using namespace std;
Help::Help() { // Constructor
}
Help::~Help() { // Destructor
}
void Help::sayName() {
cout << " ***************" << endl;
cout << " ************************************" << endl;
cout << " ************" << endl;
cout << " *********************" << endl;
}
Use
g++ main.cpp Help.cpp
You have to tell the compiler all the files that you want it to compile, not just the first one.
You should add help.o to your g++ line:
g++ -c help.cpp -o help.o
g++ help.o main.cpp
By splitting it to two lines you can save compilation time (in case of larger projects), because you can compile help.cpp only when it was changed. make and Makefile used well will save you a lot of headache:
#Makefile
all: main
main: help main.cpp
g++ -o main help.o main.cpp
help: help.cpp
g++ -c -o help.o help.cpp
I had the same problem with my Linux Lubuntu distribution and it was creating the problem for my constructor and destructor. It was not recognizing them.
Actually, this goes off if you just compile all of the three files together. So, once you saved all your files, just do this:
g++ main.cpp Help.h Help.cpp
./a.out
./a.out is the executable file for the Linux. Sorry, but I don't know about the Windows. And your program would run smoothly.
I moved from Windows to Ubuntu and I wanted to try some C++ programming on Ubuntu. So here is very simple code and very stupid error which I can't resolve:
horse.h
#ifndef _horse_
#define _horse_
class Horse{
int speed;
public:
void saySomething();
};
#endif
horse.cpp
#include "horse.h"
#include <iostream>
using namespace std;
void Horse::saySomething(){
cout << "iiiihaaaaaaa brrrrr."<<endl;
}
and Main.cpp
#include "horse.h"
int main(){
Horse h;
h.saySomething();
}
After I compile (compilation is successful) and run this I get this error message:
/tmp/ccxuDyrd.o: In function `main':
Main.cpp:(.text+0x11): undefined reference to `Horse::saySomething()'
collect2: ld returned 1 exit status
Please help me somehow.
Try
g++ -c main.cpp horse.cpp (to compile)
g++ -o a.out main.o horse.o (to link)
It seems you only compiled your code but did not link the resulting object files. You probably invoked the compiler like this:
g++ main.cpp
You should instead compile every *.cpp file separately and then link each resulting *.o file. And you should do this with a Makefile.
Actually, the basic idea is the same on Windows with MSVC. The compiler produces object files, the linker links them together.
When I run and build a simple program, it fails.
Here is the error message:
g++ -Wall -o "main" "main.cpp" (in directory: /home/markuz/Desktop)
/tmp/ccHV9wPu.o: In function main':
main.cpp:(.text+0x11): undefined reference toTest::display()'
collect2: ld returned 1 exit status
Compilation failed.
Here are the files. The compile and build command is the default of geany 1.22
//main.cpp
#include "imba.h"
int main(){
Test t;
t.display();
return 0;
}
//imba.h
class Test{
public:
void display();
};
//imba.cpp
#include <iostream>
#include "imba.h"
void Test::display(){
std::cout << "oi";
}
Any ideas about this?
Thanks.
You need to also add the imba.cpp file in the compilation step. Although you have included the header in your main file, you have not compiled the source for it and so the linker cannot find the object file for imba.cpp - that is what the error is complaining about
I can't seem to get the errors to go away. The errors are below. I have looked on Google Search and still I can't figure it out. It is not like I am new to C++, but I have not fooled around with it in a while.
The weird thing is it worked with g++ on Windows...
Errors using:
g++ main.cpp
Output:
/tmp/ccJL2ZHE.o: In function main': \ main.cpp:(.text+0x11): undefined reference to Help::Help()'
main.cpp:(.text+0x1d): undefined reference to Help::sayName()' \ main.cpp:(.text+0x2e): undefined reference to Help::~Help()'
main.cpp:(.text+0x46): undefined reference to `Help::~Help()'
collect2: ld returned 1 exit status
File main.cpp
#include <iostream>
#include "Help.h"
using namespace std;
int main () {
Help h;
h.sayName();
// ***
// ***
// ***
return 0;
}
File Help.h
#ifndef HELP_H
#define HELP_H
class Help {
public:
Help();
~Help();
void sayName();
protected:
private:
};
#endif // HELP_H
File Help.cpp
#include <iostream>
#include "Help.h"
using namespace std;
Help::Help() { // Constructor
}
Help::~Help() { // Destructor
}
void Help::sayName() {
cout << " ***************" << endl;
cout << " ************************************" << endl;
cout << " ************" << endl;
cout << " *********************" << endl;
}
Use
g++ main.cpp Help.cpp
You have to tell the compiler all the files that you want it to compile, not just the first one.
You should add help.o to your g++ line:
g++ -c help.cpp -o help.o
g++ help.o main.cpp
By splitting it to two lines you can save compilation time (in case of larger projects), because you can compile help.cpp only when it was changed. make and Makefile used well will save you a lot of headache:
#Makefile
all: main
main: help main.cpp
g++ -o main help.o main.cpp
help: help.cpp
g++ -c -o help.o help.cpp
I had the same problem with my Linux Lubuntu distribution and it was creating the problem for my constructor and destructor. It was not recognizing them.
Actually, this goes off if you just compile all of the three files together. So, once you saved all your files, just do this:
g++ main.cpp Help.h Help.cpp
./a.out
./a.out is the executable file for the Linux. Sorry, but I don't know about the Windows. And your program would run smoothly.