Klasse in Übersetzungseinheit auslagern
-
Hallo!
Ich bin in C++ ein totaler NewBee, habe gestern erst damit angefangen. Zuerst habe ich mir die Anfänge eines Tutorials angeschaut, bis ich zu den Themen Klassen und Übersetzungseinheiten gekommen bin. Alleine habe ich beide Themen glaube ich begriffen (jedenfalls das, was im Tutorial behandelt wurde).
Um das ganze auszuprobieren, habe ich ein Programm geschrieben, das ganze Zahlen in Binärzahlen umrechnet. Um den Umgang mit Klassen zu üben habe ich dafür eine Klasse angelegt.
So weit hat alles funktioniert. Wenn ich jedoch jetzt versuche die Klasse in eine extra Datei auszulagern treten beim Kompilieren Fehler auf. Ist ja auch selbstverständlich, da die verwendeten Funktionen und Variablen in main() nicht existieren. Also habe ich versucht eine head.h per #include einzubinden und weiß jetzt aber nicht, was ich reinschreiben muss. Ich kann darin ja einfach Variablen und Funktionen angeben, aber wie mache ich das mit Klassen?Ich habe eine main.cpp:
#include <iostream.h> #include "head.h" void main() { cout << "Diese Programm ist dazu da, dezimale Zahlen in Binaere Zahlen umzuwandeln." << endl << "Geben Sie hier Ihre Zahl ein: "; int dec_var; cin >> dec_var; dec2bin bin_var(dec_var); cout << "Binaer lautet diese Zahl: " << bin_var.bin; };
und eine dec2bin.cpp:
#include <math.h> #include "head.h" class dec2bin { private: bool anfang; public: string bin; dec2bin(int dec_var) { anfang = false; bin = ""; for (int n = 10; n >=0; --n) { if (dec_var/pow(2,n) >= 1) { bin = bin + "I "; dec_var -= pow(2,n); anfang = true; } else if (anfang == true) bin = bin + "O "; }; }; };
Kann mir hier jemand helfen, was ich nun in meine head.h schreiben muss? Mir würde auch ein Link schon weiterhelfen, bei dem das ganze erklärt wird. Habe dazu nämlich nichts gefunden.
Danke schonmal!
Michael
-
head.h:
#ifndef HEADOFMYHEADERFILE_H #define HEADOFMYHEADERFILE_H #include <cmath> #include <string> class dec2bin { private: bool anfang; public: std::string bin; // btw: vermeide public-Variablen! dec2bin (int dec_var); }; #endif
head.cpp:
#include "head.h" using namespace std; dec2bin::dec2bin(int dec_var) { anfang = false; bin = ""; for (int n = 10; n >=0; --n) { if (dec_var / pow(2, n) >= 1) { bin = bin + "I "; // operator += verwenden! dec_var -= pow(2,n); anfang = true; } else if (anfang /* == true*/) // das kannst du dir sparen bin = bin + "O "; // siehe oben }; };
Anmerkungen:
- ich würde die Headerdatei .hpp nennen, aber das ist letztendlich Geschmackssache
- es gibt auch für std::string einen operator +=
- so etwas packt man in eine Funktion und nicht in eine KlasseMoritz
-
zur erläuterung der präprozessorbefehle:
#ifndef HEADOFMYHEADERFILE_H #define HEADOFMYHEADERFILE_H ... #endif
das ist ein include-wächter, der verhindert, dass, wenn die datei mehrfach included wurde, alles noch einmal neu erstellt wird.
-
audacia schrieb:
btw: vermeide public-Variablen!
in diesem Fall aber unvermeidlich, da ich ja in main() darauf zurückgreife, oder?
audacia schrieb:
- es gibt auch für std::string einen operator +=
Oh, das wusste ich nicht
Dachte das währe nur um Rechenoperationen durchzuführen.
audacia schrieb:
- so etwas packt man in eine Funktion und nicht in eine Klasse
Ich weiß, das Beispiel war nur dafür da, damit ich den Umgang mit Klassen üben kann. Mir ist nichts besseres dazu eingefallen
audacia schrieb:
public:
std::string bin; // btw: vermeide public-Variablen!warum ist hier das "std::" nötig? Wenn ich es weglasse, sagt mir der Compiler
"Type name expected" und "Declaration missing ;"Sehe ich es richtig, dass mein Problem war, dass ich die Klasse doppelt erstellt habe?
-
btw:
was heißt#include <cmath>
#include <string>? Enden Includes nicht normalerweise auf .h ?
Sorry wegen Doppel-Post, ich sollte mich mal registrieren
-
hab hier ma ne andere lsg vorbereitet
head.h
#include <algorithm> #include <string> class dec2bin { public: dec2bin(unsigned int nr); std::string getBin()const; private: std::string bin; };
head.cpp
#include "head.h" dec2bin::dec2bin(unsigned int nr) { bin=""; bin+=(nr%2+48); for(;nr/=2;) bin+=(nr%2+48); std::reverse(bin.begin(),bin.end()); //weiß net genau, ob das std:: hier hin muss :rolling_eyes: } string dec2bin::getBin()const{return bin;}
main.cpp
#include <iostream> using namespace std; int main() { int i=344; //oder irgendwas kleiner (2^32)-1 ;) dec2bin a(i); cout << a.getBin() << endl; //101011000 return 0; }
...und alles ohne <cmath>
lets rock? Enden Includes nicht normalerweise auf .h ?
ja schon, aber es gibt da ausnahmen, stehen im VC98/Include verzeichniss, einfach ma nachlesen
mfg
-
Michael88 schrieb:
audacia schrieb:
btw: vermeide public-Variablen!
in diesem Fall aber unvermeidlich, da ich ja in main() darauf zurückgreife, oder?
Nein; falls es ein Member einer Klasse sein muß, greift man über eine get-Funktion darauf zu, in deinem Fall macht es allerdings keinen Sinn, die Funktion in eine Klasse zu schreiben.
Michael88 schrieb:
audacia schrieb:
public:
std::string bin; // btw: vermeide public-Variablen!warum ist hier das "std::" nötig? Wenn ich es weglasse, sagt mir der Compiler
"Type name expected" und "Declaration missing ;"Damit greifst du auf den Namensbereich std zu, in dem sämtliche Klassen und Funktionen der Standardbibliothek enthalten sind. Namespaces kommen aber in deinem Tutorial sicher später noch dran
Michael88 schrieb:
Sehe ich es richtig, dass mein Problem war, dass ich die Klasse doppelt erstellt habe?
Wie meinst du das jetzt?
Michael88 schrieb:
was heißt
#include <cmath>
#include <string>? Enden Includes nicht normalerweise auf .h ?
In C enden sie auf .h; da die C-Standardbibliothek in C++ auch verfügbar ist, kannst du sie auch verwenden. Für die Verwendung der C-Funktionen in einem C++-Programm ist aber (wegen des Namespace std; in C gibt es keine Namespaces) empfohlen, die C++-Pendante zu verwenden. Die Headerdateien der C++-Standardbibliothek haben keine Endungen; solltest du also mal irgendwo Sachen wie
#include <iostream.h>
sehen: so war das vor der Standardisierung von C++, vom aktuellen Sandard werden diese Headerdateien nicht mehr unterstützt.
Die C-Header haben 'c' als Präfix (cmath, cstdlib etc.), die C++-Header haben keines (iostream, vector etc.).Moritz
-
Ah OK, danke.
WegenSehe ich es richtig, dass mein Problem war, dass ich die Klasse doppelt erstellt habe?
Da habe ich ganz vergessen zu sagen, was bei meinem Versuch für eine Meldung kam. Ist im Nachhinein auch nicht so wichtig.
Also die Lösung für mein jetziges Problem habe ich jedenfalls. Die beiden hauptsächlichen Fehler waren, dass ich in der dec2bin.cpp (hier oft head.cpp genannt) die komplette klasse nocheinmal hingeschrieben habe, dabei soll da nur nochmal die funktion hin, und dass ich das "std::string bin" ohne das std:: hatte. Ich werde mich jetzt mal weiter vorarbeiten und verstehe dann hoffentlich noch, was genau es zu bedeuten hat
Danke nochmal!
Michael