Eclipse, C++: undefined reference

Gast #4856891
Lesenswert?

Guten Mittag,

ich habe das Problem in Eclipse, dass von meinem C++ Klassen nur jene 
verwendet werden können, welche nicht in Header und Source Dateien 
getrennt sind.

Genauer gesagt, wenn ich per #include einen Klassen-Header einfüge kann 
ich nur jene Methoden verwenden, welche direkt im Header auch 
definiert+deklariert sind.

Jene Methoden, welche in einer Sourcedatei deklariert werden, werfen den 
undefined-reference Fehler.

In den Projekteinstellungen ist als Source-Verzechnis das entsprechende 
Verzeichnis bereits eingestellt.

Kann mir jemand helfen? Danke!
#4856905
Lesenswert?

In die Header-Datei gehört die Deklaration einer Klasse: Wie heißen die 
Member, wie heißen die Methoden.

In die cpp-Datei gehört die Implementierung der Klasse, also der Code 
der beim Aufruf der Methoden ausgeführt werden soll. Alle 
Sourcecode-Dateien, die eine bestimmte Klasse verwenden wollen, 
inkludieren die Header-Datei jener Klasse.
Gast #4856911
Lesenswert?

Ok, fangen wir mal so an. Wenn ich in der main.cpp statt
1
#include "testklasse.hpp"
folgendes benutze;
1
#include "testklasse.cpp"
dann funktioniert der Code.

Main.cpp:
1
#include <iostream>
2
#include "testklasse.hpp"
3

4
int main(void) {
5
    testklasse t;
6
    t.ausserhalb();
7
    t.c = 0;
8
    t.innerhalb();
9
    int x = 0;
10
    x++;
11
    x++;
12
    x--;
13

14
        std::cout << "Hello World1" << std::endl; /* prints Hello World */
15
        std::cout << "Hello World2" << std::endl; /* prints Hello World */
16
        std::cout << "Hello World3" << std::endl; /* prints Hello World */
17
        std::cout << "Hello World4" << std::endl; /* prints Hello World */
18
        return 0;
19
}

testklasse.hpp:
1
#ifndef TESTKLASSE_H_
2
#define TESTKLASSE_H_
3

4
class testklasse {
5
public:
6
  //testklasse();
7
  void ausserhalb();
8
  char c;
9
  void innerhalb(){
10
    c = 1;
11
  };
12
};
13

14
#endif /* TESTKLASSE_H_ */

testklasse.cpp:
1
#include "testklasse.hpp"
2

3
void testklasse::ausserhalb(){
4
  c = 1;
5
}
Gast #4856921
Lesenswert?

Build Log+Screenshot:
1
03:56:04 **** Incremental Build of configuration Build (GNU) for project Test ****
2
make all 
3
make  all-recursive
4
make[1]: Verzeichnis »/home/nils/workspace/Test« wird betreten
5
Making all in src
6
make[2]: Verzeichnis »/home/nils/workspace/Test/src« wird betreten
7
arm-dey-linux-gnueabi-g++  -march=armv5te -marm -mthumb-interwork --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi -DHAVE_CONFIG_H -I. -I..   --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi  -g -O0  --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi -MT Test.o -MD -MP -MF .deps/Test.Tpo -c -o Test.o Test.cpp
8
mv -f .deps/Test.Tpo .deps/Test.Po
9
../arm-dey-linux-gnueabi-libtool  --tag=CXX   --mode=link arm-dey-linux-gnueabi-g++  -march=armv5te -marm -mthumb-interwork --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi  -g -O0  --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi  --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi -o Test Test.o  
10
arm-dey-linux-gnueabi-libtool: link: arm-dey-linux-gnueabi-g++ -march=armv5te -marm -mthumb-interwork --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi -g -O0 --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi --sysroot=/opt/dey/1.6.8/sysroots/armv5te-dey-linux-gnueabi -o Test Test.o 
11
Test.o: In function `main':
12
/home/nils/workspace/Test/src/Test.cpp:16: undefined reference to `testklasse::ausserhalb()'
13
collect2: error: ld returned 1 exit status
14
make[2]: Verzeichnis »/home/nils/workspace/Test/src« wird verlassen
15
make[1]: Verzeichnis »/home/nils/workspace/Test« wird verlassen
16
make[2]: *** [Test] Fehler 1
17
make[1]: *** [all-recursive] Fehler 1
18
make: *** [all] Fehler 2
19

20
03:56:05 Build Finished (took 688ms)
Angehängte Dateien:
Gast #4856939
Lesenswert?

Du benutzt ein Makefile mit automake. Das Problem hat also nichts mit 
eclipse zu tun, sondern damit dass du deine testklasse.cpp nicht in die 
Makefile.am eingetragen hast. Wenn du ein normales eclipse C++ Projekt 
anlegst brauchst du so etwas nicht zu tun, dann kompiliert eclipse 
automatisch alle .cpp Dateien im Projekt.
Gast #4856963
Lesenswert?

Eichhörnchen schrieb:
> Tatsache. Kann ich dort etwas eintragen wie, oder muss ich ab jetzt jede
> Source Datei von Hand dort eintragen:
>
>
1
> Test_SOURCES = *.cpp
2
>

Ein entschiedenes "kommt darauf an".

Wenn in deinem Projekt(*) Buildvarianten sind, hast Du von dir selbst 
bestimmte Kriterien, welche Quellcodedateien bei welchem Builddurchlauf 
dazugehören.

Z.B. UnitTest Quellcode habe ich gerne gleich bei den eigentlichen 
Quelldateien, gehört aber definitiv nicht in den Buildrun der 
production deliverable Binaries baut.

(* habe das Wort "Projekt" schon ziemlich über: damit ist in jeder Ecke 
wieder was Anderes gemeint... Grrr!)
#4856977
Lesenswert?

Dr. Sommer schrieb:
> Eichhörnchen schrieb:
>> folgendes benutze;#include "testklasse.cpp"
>> dann funktioniert der Code.
> Das ist aber furchtbar falsch. Sobald dein Projekt wächst geht das
> schief.
>
> Eichhörnchen schrieb:
>> int main(void) {
> Das "void" ist überflüssig.

Das ist zwar jetzt off-topic:

In C bedeutet main() eine Funktion mit beliebiger (!) Parameterliste, 
und main(void) eine mit leerer Parameterliste.

In C++ bedeutet main() eine Funktion mit leerer Parameterliste.

Da main() lt. Standard genau die beiden möglichen Signaturen

1) main() / main(void)
2) main(int, char**)

hat, ist also main() in C falsch. Denn es bedeutet ja eine beliebige 
Parameterliste, und bspw. ein main(double) ist nicht zugelassen bzw. 
wird nicht als Startpunkt des User-Codes interpretiert.

s.a.

http://en.cppreference.com/w/c/language/main_function
http://en.cppreference.com/w/c/language/function_declaration

Ok, das war jetzt etwas Erbsenzählerei ....

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren