Forum: PC-Programmierung Methoden in separater Datei definieren?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bjoern Strohstrumpf (Gast)


Lesenswert?

Hallo guten Tag,
ich habe eine Klassenbeschreibung in einem Headerfile.
Unter dieser wollte ich eine Definition von einigen Methoden 
durchführen.
Aber es scheint nicht zu klappen.
Wenn ich die Definition in eine .cc Datei schreibe funktioniert es ...
Auch wenn ich einen Operator überladen möchte muss ich das in einer 
seperaten Datei machen.
Aber warum?
1
multiple definition of `CClass::extraFileWhy()';

Danke sehr

von Ein T. (ein_typ)


Lesenswert?

Bjoern Strohstrumpf schrieb:
>
1
> multiple definition of `CClass::extraFileWhy()';
2
>

Wie sieht Dein Code denn aus?

von DerEinzigeBernd (Gast)


Lesenswert?

Bjoern Strohstrumpf schrieb:
> ich habe eine Klassenbeschreibung in einem Headerfile.
> Unter dieser wollte ich eine Definition von einigen Methoden
> durchführen.

Meinst Du so etwas:

1
class bla
2
{
3
  bla();
4
  ~bla();
5
6
  int fusel();
7
}
8
9
int bla::fusel()
10
{
11
  return (1);
12
}

> Aber es scheint nicht zu klappen.

Richtig, denn das ist falsch. Die Implementierung der Funktionen 
("Methode" nennt man das nur in anderen Programmiersprachen) gehören in 
die Klassendeklaration oder eine getrennte Quelltextdatei (*.cpp oder 
was auch immer die Religion vorgibt)

Für ersteres also
1
class bla
2
{
3
  bla();
4
  ~bla();
5
6
  int fusel()
7
  {
8
    return (1);
9
  }
10
}

von Bjoern Strohstrumpf (Gast)


Lesenswert?

DerEinzigeBernd schrieb:
> gehören

Weiß jemand warum?

von Thomas F. (tommf)


Lesenswert?

Bjoern Strohstrumpf schrieb:
> Weiß jemand warum?

Weil bei der Definition der Funktion deren Code erzeugt wird. Dies ist 
im Gensatz zur Deklaration, wo nur angeben wird, dass es die Funktion 
mit bestimmten Parametern und Rückgabetyp gibt. Die Headerdatei wird 
i.d.R. in mehrere Sourcedateien eingebunden. Enthält sie 
Funktionsdefinitionen, werden diese dadurch auch in den verschiedenen 
Objektdateien erzeugt. Der Linker findet dann mehrere identische 
Funktionen und gibt den oben angegebenen Fehler aus.

von Bjoern Strohstrumpf (Gast)


Lesenswert?

Thomas F. schrieb:
> Bjoern Strohstrumpf schrieb:
>> Weiß jemand warum?
>
> Weil bei der Definition der Funktion deren Code erzeugt wird. Dies ist
> im Gensatz zur Deklaration, wo nur angeben wird, dass es die Funktion
> mit bestimmten Parametern und Rückgabetyp gibt. Die Headerdatei wird
> i.d.R. in mehrere Sourcedateien eingebunden. Enthält sie
> Funktionsdefinitionen, werden diese dadurch auch in den verschiedenen
> Objektdateien erzeugt. Der Linker findet dann mehrere identische
> Funktionen und gibt den oben angegebenen Fehler aus.

Also ich deklariere in class.hpp meine Klasse. Diese wird dann bei 
class.cpp eingefügt wegen #include?

Dann wird die Deklaration wieder in main.cpp mit define eingefügt.

Dem Compiler mache ich über gcc main.c class.cpp bekannt welche Dateien 
es gibt.

Warum muss man eigentlich nicht die Headerdatei angeben? Findet der 
Linker die dann über den Pfad in include im Ordner ?

class.hpp
1
class class{
2
 class();
3
};


class.cpp
1
#include "class.hpp"
2
class::class(){}


main.cpp
1
include "class.hpp"
2
int main(){
3
 return 1;
4
}

von Bob the Belcher (Gast)


Lesenswert?

Hallo

Thomas F. schrieb:
> Weil bei der Definition der Funktion deren Code erzeugt wird. Dies ist
> im Gensatz zur Deklaration, wo nur angeben wird, dass es die Funktion
> mit bestimmten Parametern und Rückgabetyp gibt. Die Headerdatei wird
> i.d.R. in mehrere Sourcedateien eingebunden. Enthält sie
> Funktionsdefinitionen, werden diese dadurch auch in den verschiedenen
> Objektdateien erzeugt. Der Linker findet dann mehrere identische
> Funktionen und gibt den oben angegebenen Fehler aus.

Leicht O.T.

Sicherlich sind deine Ausführungen korrekt und du scheinst dich auch 
angestrengt haben klar und deutlich zu erklären.

Aber:
Wenn man das (stellvertretend eigentlich für alle Texte und 
"Erklärungen" aus dem Umfeld)  so durchliest:

Wer wundert sich eigentlich ernsthaft das es gefühlt Ewigkeiten dauert 
bis man auch nur andeutungsweise durchblickt wie Programmierung, ganz 
unabhängig von der jeweiligen Sprache,  funktioniert - bis man 
andeutungsweise ein Bauchgefühl für Programmierung erlangt.

Das muss doch auch besser gehen - aber abgesehen von arg eingeschränkten 
"Kinderprogrammiersprachen" die meist auch noch Produkt bezogen sind und 
mit "echter" Programmierung wenig zu tun hat, habe ich bis jetzt noch 
keine Programmiersprache kennengelernt die man als erste "richtige" 
Programmiersprache einfach versteht und eine nachvollziehbare 
Alltagslogik hat sondern immer komische Konzepte, kryptische  und 
doppeldeutige Bezeichnungen, 1001 Verweise, Abhängigkeiten über 20 Ecken 
usw.

Wenn man einmal irgendwie einmal das Konzept verstanden hat dann sind 
neue Programmiersprachen auch nur noch keines Problem - nur es dauert 
und zumindest von mir kann ich es nicht sagen wie, warum  und wann ich 
die Konzepte und das komische "Denken dahinter" verstanden hatte.

(Bei mir hat es irgendwann mal Klick gemacht - aber was der Auslöser war 
kann ich nicht erklären -

Und was das Erklären angeht: Ich selbst könnte einen absoluten Anfänger 
auch nicht die Ideen und das komische Denken hinter "richtigen" 
Programmiersprachen erklären - scheinbar kann das wohl aber auch 
niemand wie ich es selbst erfahren musste)

von Luitpold (Gast)


Lesenswert?

Bob the Belcher schrieb:
> Wer wundert sich eigentlich ernsthaft das es gefühlt Ewigkeiten dauert
> bis man auch nur andeutungsweise durchblickt wie Programmierung, ganz
> unabhängig von der jeweiligen Sprache,  funktioniert - bis man
> andeutungsweise ein Bauchgefühl für Programmierung erlangt.

Nein. Ernstgemeinte Werkzeuge erfordern, daß man sich mit ihnen länger 
als fünf Minuten auseinandersetzt. Es sind keine Kinderspielzeuge, und 
sie sind auch nicht dafür da, als Lernwerkzeuge genutzt zu werden, 
sondern zum Arbeiten.

Bob the Belcher schrieb:
> habe ich bis jetzt noch
> keine Programmiersprache kennengelernt die man als erste "richtige"
> Programmiersprache einfach versteht

Nicht jedem ist es gegeben, mit Programmiersprachen zu arbeiten. Das ist 
nicht weiter schlimm, nicht jeder kann Noten lesen, Bilder malen oder 
erträglich Geige spielen. Und nicht jeder hat das Zeug, mehrere 
Fremdsprachen zu erlernen, oder Mathematik, oder auch das Reiten.

Wieso sollten Programmiersprachen etwas sein, was man "einfach 
versteht"? Was ist das für ein merkwürdiges Anspruchsdenken?

von Ein T. (ein_typ)


Lesenswert?

Bjoern Strohstrumpf schrieb:
> Also ich deklariere in class.hpp meine Klasse. Diese wird dann bei
> class.cpp eingefügt wegen #include?

Genau, #include kopiert den Inhalt der Datei einfach.

Deswegen verwendet man sogenannte Include Guards, um ein mehrfaches 
Einbinden derselben Deklarationen und Definitionen zu unterbinden.

> Warum muss man eigentlich nicht die Headerdatei angeben? Findet der
> Linker die dann über den Pfad in include im Ordner ?

Ja.

von DerEinzigeBernd (Gast)


Lesenswert?

Ein T. schrieb:
>> Warum muss man eigentlich nicht die Headerdatei angeben? Findet der
>> Linker die dann über den Pfad in include im Ordner ?
>
> Ja.

Nein.

Der Linker bekommt keine dieser Dateien zu Gesicht, der sieht nur die 
vom Compiler aus diesen Dateien erzeugte Objektdatei. Die heißt oft *.o 
(aber das ist nicht standardisiert, manche Compiler verwenden auch 
*.obj).

Der Linker packt alle zum Projekt gehörenden Objektdateien und den 
Startup-Code zusammen und versucht, alle externen Referenzen dadurch 
aufzulösen, daß er in allen übergebenen Libraries* nach diesen 
Referenzen sucht und bei Treffern die jeweilige Objektdatei aus der 
Library herauslöst und zum Programm dazupackt.

*) oft *.a, bei manchen Systemen aber auch *.lib

von Wilhelm M. (wimalopaan)


Lesenswert?

Bjoern Strohstrumpf schrieb:
> Also ich deklariere in class.hpp meine Klasse. Diese wird dann bei
> class.cpp eingefügt wegen #include?

Ja.
#include ist eine Präprozessor-Direktive. Und der Präprozessor ist ein 
nicht-interaktiver Editor.

> Dann wird die Deklaration wieder in main.cpp mit define eingefügt.

Ja.

> Dem Compiler mache ich über gcc main.c class.cpp bekannt welche Dateien
> es gibt.

Strenggenommen dem Compiler-Frontend, was (theoretisch) Präprozessor / 
Compiler für jede Übersetzungseinheit aufruft und am Ende den Linker.

> Warum muss man eigentlich nicht die Headerdatei angeben?

Die hat der Präprozessor ja schon in die Quelldatei "hinein editiert".

> Findet der
> Linker die dann über den Pfad in include im Ordner ?

Nein (s.o.).

Damit wir hier diese Grundlagen der Compilation bzw. was bedeutet 
Deklaration und was ist eine Definition inklusive der ODR wiederholen 
müssen, nimm einfach mal ein C++ Buch zur Hand ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.