Undefined reference to `TESTCLASS::TESTCLASS()' - c++

Although I read a few google-results for that error I can't find my problem for this error, not even while trying to reduce everything to its very basic content.
That's my testclass.h:
class TESTCLASS {
public:
TESTCLASS();
};
int x; // I added this for testing if the file is included from my main code file
x=10; // It is and throws this error: testclass.h:8:1: error: 'x' does not name a type, which I don't understand neither, but it't not the main problem here
testclass.cpp:
#include "testclass.h"
TESTCLASS::TESTCLASS() {
// do some stuff
}
and here's my main code file:
#include "lib/testclass.h"
TESTCLASS test;
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}
This throws the error
/var/folders/b5/qc8dstcn02v_hyvgxsq4w9vr0000gq/T//ccQOziAu.ltrans0.ltrans.o: In function `_GLOBAL__sub_I_test':
/Volumes/Daten/stefanherzog/Documents/Nextcloud/Programmierung/Arduino/200515_growboxLibrary_test/200515_growboxLibrary_test.ino:3: undefined reference to `TESTCLASS::TESTCLASS()'
collect2: error: ld returned 1 exit status
exit status 1
So even this is very basic I can't see the problem! I'm using an avr-g++ compiler within my Arduino IDE (v1.8.12).
Can someone please explain me what I'm doing wrong?

it looks like you don't send testclass.cpp to your compiler. If so, your problem does'nt come from your code but your compiling command line.
Using gcc you should have something like :
g++ main.cpp lib/testclass.cpp -o testclass
I don't know the compilation process for arduino but i hope it will helps you finding the solution.

Easiest put testclass.cpp into the same folder as your .ino file. It should show up as a separate tab.
Put testclass.h there as well. and remove the lib subfolder.
And remove the int x=10; definition from the .h file. If both units are including testclass.h, that should end up in a duplicate error.
BTW: an assignment x=10; outside a function is nonsense anyway.

When using subdirectories with the Arduino IDE the subdirectory needs to be named as utility. That's actually it!
Having this structure for example (in ../Arduino/libraries/):
./testclass
./testclass/testclass.h
./testclass/testclass.cpp
./testclass/sub
./testclass/sub/sub.h
./testclass/sub/sub.cpp
testclass.h:
#ifndef __TESTCLASS_H__
#define __TESTCLASS_H__
#include "utility/sub.h"
class TESTCLASS {
public:
TESTCLASS();
};
#endif
testclass.cpp:
#include "testclass.h"
TESTCLASS::TESTCLASS() {
// do some stuff
}
sub.h:
class SUBCLASS {
public:
SUBCLASS();
};
sub.cpp:
#include "sub.h"
SUBCLASS::SUBCLASS() {
// do some stuff
}
You can simply include the "main" testclass.h in your project and instantiate the class and even the subclass:
#include <testclass.h>
TESTCLASS test;
SUBCLASS sub;
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}

Related

Error: Multiple definitions of function in C++ class [duplicate]

This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 5 months ago.
I don't know how to add functions of a class outside its scope to it, use them in another class and then compile it.
MyMain.cpp
#include"MyClass.cpp"
int main(){
MyClass myClass;
myClass.run();
}
MyClass.cpp
#ifndef MYCLASS_CPP
#define MYCLASS_CPP
#include<iostream>
class MyClass {
private:
void usage();
public:
void run();
};
void MyClass::usage(){
std::cout << "usage called" << std::endl;
}
void MyClass::run(){
usage();
}
#endif
I try to compile it with:
g++ MyMain.cpp MyClass.cpp -o main
With that I get the following error message:
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::usage()':
MyClass.cpp:(.text+0x0): multiple definition of `MyClass::usage()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x0): first defined here
/usr/bin/ld: /tmp/ccN7GfOD.o: in function `MyClass::run()':
MyClass.cpp:(.text+0x38): multiple definition of `MyClass::run()'; /tmp/ccLhxS6v.o:MyMain.cpp:(.text+0x38): first defined here
collect2: error: ld returned 1 exit status
If I have understood the concept correctly, the function headers within the class serve only as placeholders. The actual functionality is then "overwritten" by the external functions, which also contain a body.
And why does the error message say, that the function is already defined in the MyMain.cpp?
I have also seen that there are many similar questions here, but unfortunately I could not expand my understanding of the basic problem to solve it.
Is it possible that I am using the command to build the class with C++ incorrectly or that I can save the #include "MyClass.cpp"?
Kind regards
Several things wrong. here's the steps to put it right
Rename MyClass.cpp to MyClass.h.
Create a new empty file MyClass.cpp
Move the function definitions MyClass::usage() { .. } and MyClass::run() { .. } from MyClass.h to MyClass.cpp. You should probably also move #include <iostream> but this is not essential.
Add #include "MyClass.h" to MyClass.cpp
Change #include "MyClass.cpp" to #include "MyClass.h" in MyMain.cpp
Then build as you are doing now. That part is correct.
Essentially the technique is to separate your code into declarations and definitions. The declarations go into header files, which are included in the cpp files. The cpp files contain the definitions and are what you compile.

Failing to force the link error of a static member variable happen

Please DO NOT make my question as a duplicate. I wanted to force the error to happen!!!! I am not asking how to solve the error. Thank you.
I've heard that if a static member variable is initialised in a header file, and if the header file is included in many different source files, then a link error will occur. And I do believe that.
However, I failed to force the error happen. My program can always be complied successfully. Some say that the include guards prevent the error. It still worked even if I got rid of the include guards.
s1.h
#ifndef S1_H
#define S1_H
class S
{
public:
S();
static int num; // just make it public so that it can be used
};
int S::num = 10;
#endif // S1_H
main.cpp
#include "s1.h"
#include <QDebug>
int main()
{
qDebug() << S::num;
}
test.cpp
#include "s1.h"
#include <QtDebug>
class Test
{
public:
Test();
void printNum() {qDebug() << S::num;}
};

Calling function from different files in C++ error

I would like to use one function from Stats.cpp in Application.cpp. Here are my code snippets:
In Stats.h:
#ifndef STATS_H
#define STATS_H
class Stats
{
public:
void generateStat(int i);
};
#endif
In Stats.cpp:
#include Stats.h
void generateStat(int i)
{
//some process code here
}
In Application.cpp:
int main()
{
generateStat(10);
}
I get an "unresolved external symbol" error however I don't know what I else I would need to include in order for Application.cpp. Any thoughts?
In Stats.cpp
you need to define generateStat like following :
#include Stats.h
void Stats:: generateStat(int i) // Notice the syntax, use of :: operator
{
//some process code here
}
Then create object of class Stats, use it to call the public member function generateStat
Stats s;
s.generateStat( 10 ) ;
Build the application using :
g++ -o stats Stats.cpp Application.cpp -I.
generateStat is part of your Stats class. You need to instantiate a Stats object (along with the necessary includes for Stats.h in your main class)
For example,
Stats stat;
stat.generateStat(i);
Also, your function definition needs to include the class name Stats::generateStat.
The same error msg occured 2 weeks ago (at work).
At first glance --- Try:
void Stats::generateStat(int i) {
//some process code here }
The class name was missing. Hence, unresolved.
btw Concerning your header --- another issue, this #ifndef directive should not be necessary cause you should declare Stats only once in a namespace.
#ifndef CLASS_H
#define CLASS_H
#include "Class.h"
#endif
This is a generic example - Usable in cpp files.
EDIT: Now, I saw your invocation (main method in your case). You need an object instance to invoke your method.
Stats* stats = new Stats(); //add a default constructor if not done
stats->generateStat(77);
// any other stats stuff ......
// in posterior to the last use
delete(stats);
In your header:
Stats::Stats(){}; //with an empty body - no need to write it again in the cpp file

Building fail in Eclipse C/C++ but works well in commandline

[EDIT:]
The problem seems to belong to the functions, that take default-parameters. Without separating in *.h *.cpp and main file it worked as i implemented something like:
void foo(double db;); // deklaration
void foo(double db = 4){ cout << db;} // definition
int main(){
foo(); // usage
return 1;
}
But if I separate deklaration (-> *.h), definition (-> *.cpp) and usage (-> main) compiling suddenly returns an erro telling, there is no function foo(void), as it does not recognize that there is a default parameter. Any suggestions for that?
[/EDIT]
I wrote a c++-program running somehow like:
#include <iostream>
/* other includes */
using namespace std;
class my_class
{
private:
/* variables */
public:
/* function deklarations (just some short ones are only defined not declared) */
};
ostream& operator<<(ostream &out, my_class member);
/* Definition of the member functions and of the not-member-function */
int main()
{
/*some trial codes of member-functions */
return 1;
}
In one total file all compiled well in Eclipse and worked. Now I also wanted to try seperate in a main,class-header and class-cpp file (called them "my_class.h" and my_class.cpp").
For that i put in class-header:
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
#include <iostream>
/* other includes */
using namespace std;
class my_class
{
/* ... */
};
ostream & operator<<(ostream &out, my_class member);
#endif /* MY_CLASS_H_ */
I put in class-cpp:
/* Definition of the member functions and of the not-member-function */
I put in main:
#include <iostream>
#include "my_class.h"
#include "my_class.cpp"
int main()
{
/*some trial codes of member-functions */
return 1;
}
This version is compiling with the g++ command in commandline:
g++ -o main.exe main.cpp
But it does not Compile in Eclipse. There it gives me the Error:
...\my_class.cpp:11.1: error: 'my_class' does not name a type
and same for all other member functions and variables. I tried to follow the instructions from here (I put just "my_class.h" in main and my_class.cpp, but then it did not compile in Eclipse and in command line (of course then with the my_class.cpp included). Eclipse gives me an Error, that makes me believe Eclipse does not see the "my_class.cpp":
...\main.cpp:288:47: error: no matching function for call to 'my_class::foo(...)'
where foo stands for the first member-function declard in the "my_class.cpp" file. First It gave the error for the constructor too, but as I put it's definition directly into the *.h file it worked well. (That's why I think, it does not see the "my_class.cpp" file)
I think I might be missing something very trivial as I am very new to Eclipse, but I don't see it. I tried to make my questions and information as short as possible.
default-parameters need to be declared in the header-file as it contains the declarations and not in the cpp file, which contains the definitions. (An additional mistake was to declare them in the definition). Found some help here. But why did it work, as I implemented it in one whole file?
Answer:
If default-parameter is in the cpp-file, the main file does not see it as
it looks only into the header-file
But if the whole code is included in just one file, the default-value
can be found in the definition too.
To explain myself:
I considered answering my question, because it gives a better overview of the whole question and the question will now not appear as unanswered. After reading this, I think that it is the right way to do so.

What is the relationship between multiple header files and classes?

I have a noob question here.
I'm getting my head around the C++ structure and syntax and I've hit a bit of a wall.
I know I am missing something from my concept. So first a little code to help describe the situation.
Control.h
#pragma once
#ifndef CONTROL_H
#define CONTROL_H
class Control
{
public:
Control();
~Control();
private:
public:
};
#endif /*CONTROL_H*/
Control.cpp
#include "Control.h"
#include "Hello.h"
Hello helloObj;
Control::Control()
{
}
Control::~Control()
{
}
int main()
{
int a = helloObj.HelloWorld();
return 0;
}
Hello.h
#pragma once
#ifndef HELLO_H
#define HELLO_H
class Hello
{
public:
Hello();
~Hello();
private:
public:
int HelloWorld(void);
};
#endif /*HELLO_H*/
Hello.cpp
#include "Hello.h"
Hello::Hello()
{
}
Hello::~Hello()
{
}
int HelloWorld()
{
return 5;
}
I try and compile control.cpp with g++ on OSX 10.7 and get
Undefined symbols for architecture x86_64:
"Hello::Hello()", referenced from:
__static_initialization_and_destruction_0(int, int)in cccZHWtd.o
"Hello::~Hello()", referenced from:
___tcf_1 in cccZHWtd.o
"Hello::HelloWorld()", referenced from:
_main in cccZHWtd.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Is it the compiler, my code or my concept of whats going on?
Am I not instantiating something correctly?
Any links describing this in more detail would be appreciated.
Ultimately I want to be able to run a function in another class and return the result...normal OO, keeping your program modular stuff....
The errors you are getting are Linking errors not compilation errors.
The linker is not able to find definitions of the said functions & hence it reports the errors. It seems You have not included the Hello.cpp file containing the function definitions in your project.
Make sure Hello.cpp is included in your project and is a part of your project or
If you are using command line for compilation and linking make sure you have specified Hello.cpp in the file names on the command line.
Most of the issue is me not being familiar as I should be with g++ (Thanks Als).
There were are few syntax issues as well (Thanks Brain).
Here is the corrected (albiet slightly bloated for an overview of stucture) code and g++ command
Control.h
#pragma once
#ifndef CONTROL_H
#define CONTROL_H
class CONTROL
{
private:
//nothing defined yet...
public:
Control(); //default constructor
~Control(); //default destructor
};
#endif /*CONTROL_H*/
Control.cpp
#include "Hello.h"
#include "Control.h"
Hello helloTest; //instantiates the Hello Object
Control::Control()
{
}
Control::~Control()
{
}
int main()
{
helloTest.HelloWorld();
return 0;
}
Hello.h
#pragma once
#ifndef HELLO_H
#define HELLO_H
class Hello
{
private:
//nothing defined yet
public:
Hello(); //default constructor
~Hello(); //default destructor
void HelloWorld();
};
#endif /*HELLO_H*/
Hello.cpp
#include "Hello.h"
#include <iostream> //so we can use 'cout'
using namespace std;
Hello::Hello()
{
}
Hello::~Hello()
{
}
void Hello::HelloWorld()
{
std::cout << "Hello lovelies!\n"; //The magic word.
}
Then we run g++ like so
g++ -o Hello ./Control.cpp ./Hello.cpp
g++ [option] [output file name] [input files]
First of all:
public:
Hello();
~Hello();
private:
public:
is pointless, a class defaults to private, and there is no need to make it
public twice nor do I know if you can do that furthermore if you have no private members private should not be in there (not trying to be mean just some advice :-) )
Now to answer the question (with a guess DISCLAIMER: I AM NOT 100% FAMILIAR WITH GCC):
This is a linker error, it may be there because
the compiler can not find the definition of
HelloWorld(void);.
Let me explain:
In your header file you wrote:
int HelloWorld(void);
However in your .cpp you write:
int HelloWorld()
{
return 5;
}
The function's (or in this case method because it is inside a class)
arguments need to be exactly the same in the header and source, you
can not even change the names (or at least you cant with VC++ which is
what I use; I have little experience with gcc) so this may be resolvable
by typing
int HelloWorld(void)
{
return 5;
}
Next (DISCLAIMER I AM NOT 100% familiar with the pre-proccsor):
You also use the #pragma once pre-proccsor tag, I dont use it but
I believe that means you can only include a file once and you have included Hello.h and Control.h twice, like I said I am no expert in the pre-proccsor but you commented out
HELLO_H
and
CONTROL_H