erstes prog mit Klassen,und direkt Fehler...
-
davie schrieb:
hm ich grübele noch über den inhalt nach, aber ich kann dir sagen:
zwischen class und struct ist der einzige unterschied:
class ist "voreingestellt" private, wie du so schön kommentiert hast; und bei struct ist es "public"
sonst gibt es nur noch einen unterschied bei der vererbung, das kann dir im prinzip egal sein.
ansonsten gibt es keine unterschiede in der verwendung von class und struct. sie sind sozusagen gleich.Öhm, in Strukturen gibt es aber keine Methoden (also Funktionen in der Klasse).
Strukturen können nur Variablen zusammenfassen, Klassen können Variablen und Funktionen zusammenfassen
-
Soso :p
Bis auf private/public gibt es wirklich keinen Unterschied, nichtmals einen versteckten
-
Huh war das falsch, was ich geschrieben habe?!
-
bei mir geht aber alleine das schon nicht,und felder auch nicht:
ratio A (1,2);
ratio B (3);
ratio C ;beim ratio c sagt er:
no matching function for call to `ratio::ratio()'
EDIT irgendwie sehe ich ga rnicht mehr durhc,kann nicht jemand mal nen beispiel aus meinen programms chrieben wo was mit nem array der klass egemahct wird ?
Das geht z.b. auch nicht...: (ist da skompliziert...)
ratio A (1,2);
ratio B (3);
ratio C[2];
ratio C[0]=ratio (1,2);ich werd wahnsinnig,dann will ich nen destruct teste,indem dadrin ein print befehl steht, rufe den im hauptprpgramm am ende mit
~ratio() auf, passiert aber nix sondenr bekomme ne fhelermeldung die vorher woanders nicht kam, und nach entfern des destructs trotzdem noch kommt.
Was ist das fürn scheiss, schriebe morgen klausur
-
ich hoffe, das kommt nicht zu spät, und du verstehst es auch
class ratio // Typdefinition // { private: int z; //du hast von außen KEINERLEI zugriff auf diese variable int n; //dito public: void print () { cout << a << '/' << b << '\n'; } void set (int a, int b) { z = a; n = b; } }; //so, jetzt willst du eine objekt haben, d.h. du instanziierst die klasse: ratio r; //Was passiert hier: /* 1. Speicher wird reserviert (in dem Fall statischer, das ist aber im Moment egal) 2. ratio::ratio() wird aufgerufen. Das ist der Konstruktor deiner Klasse. Da du selbst keinen Konstruktor definiert hast, generiert der compiler einen eigenen. Merke: Jede Klasse (Struktur) hat einen Standardkonstruktor, wenn du keinen anderen angibst. 3. Wenn das Programm beendet wird, wird der Destruktor (die Elementfunktion der Klasse mit dem Namen ~ratio aufgerufen */ int main () { ratio A; //genauso, wie oben, nur wird hier das Objekt am Stack angelegt ratio B(1); //Achtung, funktioniert nicht! /* Hier passiert folgendes: Der Compiler sucht einen passenden Konstruktor, in dem Fall z.B. ratio::ratio(int). Da du diesen aber nicht definiert hast, kann der Compiler nichts mit der Anweisung anfangen -> Fehlermeldung */ ratio C(1,2); //Hier versucht der Compiler, einen Konstruktor z.b. ratio::ratio (int, int) //zu finden. Gibt's nicht -> Fehlermeldung A.n = 10; //geht auch nicht, wie schon bemerkt, da n private ist. A.set (10, 20); //set ist eine öffentliche (public) methode. //d.h. du darfst sie aufrufen, wann immer du willst. //Damit änderst du A.z zu 10 und A.n zu 20 A.print(); //am ende der Funktion werden automatisch die Defaultdestruktoren aufgerufen } //Beispiel 2: class ratio2 { //... genauso wie ratio ratio2 () : z(1), n(1) {} //der o.g. Standardkonstruktor, selbst definiert ratio2 (int zaehler) : z(zaehler), n(1) {} ratio2 (int zaehler, int nenner) : z(zaehler), n(nenner) {} ~ratio2 () { cout << "Ratio2 wurde vernichtet!\n"; } }; void foo () { ratio2 A; ratio2 B(1); ratio2 C(2,2); //diese drei definitionen funktionieren alle nur deshalb, weil es die passenden //funktionen gibt: ratio::ratio(), ratio::ratio(int) und ratio::ratio(int,int) //jetzt machen wir ein array: ratio2 X[] = { ratio2(), ratio2(1), ratio2(1,2) }; X[0].print(); X[1].print(); X[2].print(); //am ende werden alle lokalen objekte automatisch zerstört, //d.h. nach aufrufen von foo solltest du 6 destruktormeldungen haben: //die von A, B und C und die von X[0], X[1] und X[2] }
Wenn du Probleme mit eigenen Code hast, dann poste ihn (inklusive Fehlermeldungen)
Wenn du dich wo nicht auskennst, frag nochmal und frag genauer
-
also bei beispiel 2 verstehe ich die kontruktoren in der class nicht, warum da noch ":" drin sind und so, reicht da nicht einfach als kontruktor für alle varianten sowas:
ratio(int zaehler = 0, int nenner = 1);
Hab ich jedenfalls bei mir,und geht für
ratio A;
ratio A(1);
ratio A(1,3);
ratio A[2];????
Und jetzt zu meinem prog,wo das auch so ist...
ich will den destruktor selber schrieben und ausgeben damit ich den mal sehe, aber wenn ich das mache, kommt windows-speicher fehler,und die berechnungen geben ne ganz hohe zahl aus.
Hier noch auskommentiert, beim einkommentieren treten halt die fehler auf,und kein destruk ist zu sehen:
// Hauptprogramm // Datei: rmainb1.cpp #include <stdio.h> #include "ratiob1.hpp" ratio A,B(3),C(1,2); // dreimal Kontruktor int main () { B.print(); printf(" Ausgabe von bruchzahlen\n"); A = B.addiere (&C); printf("\nAusgabe der Addition\n"); A.print(); A = B.subtrahiere(&C); printf("\nAusgabe der Differenz\n"); A.print(); A.zuweisung (2,4); printf("\nAusgabe nach der Zuweisung\n"); A.print();printf("\n\n"); return 0; }
// Beispiel 1: // Datei: ratiob1.hpp #include <stdio.h> #ifndef RATIOHEADER #define RATIOHEADER class ratio { private: int zae; int nen; public: ratio(int zaehler = 0, int nenner = 1); // ~ratio(); void print (); ratio addiere (ratio *operand2); ratio subtrahiere (ratio *operand2); void zuweisung (int , int); }; #endif
// ratio-beispiel // Datei: ratiob1.cpp #include "ratiob1.hpp" ratio::ratio (int za, int ne) { zae=za , nen=ne; } /* ratio::~ratio () { printf ("DESTRUKT"); }*/ void ratio::print () { printf ("%d/%d", zae,nen); } ratio ratio::addiere (ratio *op2) { ratio erg; erg.zae=zae* op2->nen + nen * op2->zae; erg.nen= nen * op2->nen; return erg; } ratio ratio::subtrahiere (ratio *op2) { ratio erg; erg.zae=zae* op2->nen - nen * op2->zae; erg.nen= nen * op2->nen; return erg; } void ratio::zuweisung (int za,int ne) { zae=za, nen=ne; }
-
deejay ray schrieb:
also bei beispiel 2 verstehe ich die kontruktoren in der class nicht, warum da noch ":" drin sind und so, reicht da nicht einfach als kontruktor für alle varianten sowas:
ratio(int zaehler = 0, int nenner = 1);
Hab ich jedenfalls bei mir,und geht für
ratio A;
ratio A(1);
ratio A(1,3);
ratio A[2];klar geht's so auch, ich wollte das nur hervorheben.
die : und das danach nennt man Elementinitialisierungsliste. Die sollte man dem "Initialisieren" im Konstruktorkörper vorziehen, da das kein Initialisieren ist, sondern ein ZuweisenZu deinem Programm:
// Hauptprogramm // Datei: rmainb1.cpp //#include <cstdio> //die neuen standard-header sind idR besser #include <iostream> //C++ sagt mir mehr zu ;) #include "ratiob1.hpp" using namespace std; //wegen den neuen headern. übernimm einfach das konstrukt //es wird dir noch häufig genug über den weg laufen int main () { ratio A,B(3),C(1,2); // dreimal Kontruktor //btw: globale Variablen sind schlecht! B.print(); cout << " Ausgabe von bruchzahlen\n"; A = B.addiere (&C); cout << "\nAusgabe der Addition\n"; A.print(); A = B.subtrahiere(&C); cout << "\nAusgabe der Differenz\n"; A.print(); A.zuweisung (2,4); cout << "\nAusgabe nach der Zuweisung\n"; A.print(); cout << "\n\n"; return 0; //return 0 darfst du übrigens getrost weglassen }
// Beispiel 1: // Datei: ratiob1.hpp //#include <iostream> den header brauchst du hier doch noch gar nicht #ifndef RATIOHEADER #define RATIOHEADER class ratio { private: int zae; int nen; public: ratio(int zaehler = 0, int nenner = 1); ~ratio(); void print (); ratio addiere (ratio *operand2); //referenzen wären besser ratio subtrahiere (ratio *operand2); //als zeiger void zuweisung (int , int); }; //soweit so gut #endif
// ratio-beispiel // Datei: ratiob1.cpp #include "ratiob1.hpp" #include <iostream> //erst hier brauchst du den header using namespace std; ratio::ratio (int za, int ne) : zae(za), nen(ne) {} //ist idR effektiver (für größere klassen, aber man sollte es sich angewöhnen) ratio::~ratio () { cout << "Destruktor\n"; } void ratio::print () { cout << zae << '/' << nen; } ratio ratio::addiere (ratio *op2) { return ratio(zae * op2->nen + nen * op2->zae, nen * op2->nen); //könnte schneller sein } ratio ratio::subtrahiere (ratio *op2) { return ratio(zae=zae* op2->nen - nen * op2->zae, nen= nen * op2->nen); } void ratio::zuweisung (int za, int ne) { zae=za, nen=ne; }
Was mir auffällt: bei addiere und subtrahiere hätte ich erwartet, dass
zu dem bruch selbst addiert wird, und nicht ein neuer erzeugt wird.das mit den statischen Variablen (die globalen) könnte ein grund gewesen sein, warum die ausgabe nicht funktioniert: die destruktoren werden dann nämlich erst am ende des programms (nach return 0; ) aufgerufen.
-
1. mit iostream und cout und so kam in dem buch noch nicht vor.
das programm hab ich so abgetippt und destrukt so eingefügt wie es vorher beim einfacheren programm erklärt war,auch da hats nicht geklappt.
auch wenn die variablen nicht mehr lokal sind kommt windows-speicher fehler.
wenn ich den include stdio an der besgaten stelle weglasse,kennt er in dem anderen file print fund so nicht,also muss es mit rein.
Im Kontrukter das mit sdoppelpunkt dahinter, kommt nen parse-error....
Sorry,aber ich wolte das prog so nutzen wie ichs hab und im buch steht, und wie es funzt,nur halt gerne auch mit nem destrukt,damit ich den mal sehe.
-
Hier eine andere Klasse rational (schlechtes Design, nur als funktionierendes Beispiel):
#include <iostream> #include <conio.h> class rational { private: int _z; int _n; public: //Ctor rational(); rational( int z, int n ); //Dtor ~rational(); //IO rational& eingabe(); void ausgabe(); //math rational& add( const rational& r1, const rational& r2); rational& sub( const rational& r1, const rational& r2); rational& mul( const rational& r1, const rational& r2); rational& div( const rational& r1, const rational& r2); }; rational::rational(){} rational::rational( int z, int n ) { _z = z; _n = n; } rational& rational::eingabe() { std::cin >> _z; std::cin >> _n; return *this; } rational::~rational() {} void rational::ausgabe() { std::cout << _z << "/" << _n << std::flush; } rational& rational::add( const rational& r1, const rational& r2 ) { _z = r1._z * r2._n + r1._n * r2._z; _n = r1._n * r2._n; return *this; } rational& rational::sub( const rational& r1, const rational& r2 ) { _z = r1._z * r2._n - r1._n * r2._z; _n = r1._n * r2._n; return *this; } rational& rational::mul( const rational& r1, const rational& r2) { _z = r1._z * r2._z; _n = r1._n * r2._n; return *this; } rational& rational::div( const rational& r1, const rational& r2) { _z = r1._z * r2._n; _n = r1._n * r2._z; return *this; } int main() { rational a(5,9); a.ausgabe(); std::cout << std::endl; rational b; std::cout << "Bitte Rationale Zahl eingeben (Zaehler (Space) Nenner): "; b.eingabe(); b.ausgabe(); std::cout << std::endl; rational c; c.add(a,b); c.ausgabe(); std::cout << std::endl; rational d; d.sub(a,b); d.ausgabe(); std::cout << std::endl; rational e; e.mul(a,b); e.ausgabe(); std::cout << std::endl; rational f; f.div(a,b); f.ausgabe(); std::cout << std::endl; getch(); }
-
wieso bekomme ich denn jetzt hier nur Fehlermeldungen ? habs genauso ausm Buch abgetippt;
// Implementierung der Zeilen // Zeile1.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> #include "Zeile1.hpp" Zeile::Zeile (char * text); { Laenge = strlen (text) +1 // Laenge merken Inhalt = new char[Laenge];//Speicher holen if (Inhalt == NULL) exit(1); strcpy (Inhalt,text); // Inhalt kopieren } Zeile::~~Zeile() { delete Inhalt; } void Zeile::print() { printf (Inhalt);
// Klasse mit dynamischer Speicherverwaltung // Zeile1.hpp class Zeile { int Laenge; char * Inhalt; public: Zeile (char * ctext); ~Zeile(); void print(); };
// Hauptprogramm für zeile // z1main.cpp #include <stdio.h> #include "Zeile1.hpp" int main() { Zeile z1("\nGuten Tag!\n"; z1.print(); // Inhalt ausgeben return 0; }
-
Klasse MyString, die die "Großen Drei" (Copy-Konstruktor, Zuweisungsoperator, Destruktor) in Aktion zeigt:
#include <iostream> #include <iomanip> #include <conio.h> #include <cstring> class MyString { public: MyString(char* pText=NULL); MyString(const MyString& str); // Copy-Konstruktor MyString& operator=(const MyString& str); // Zuweisungsoperator ~MyString(); void output(); void showaddress(); private: char* pText_; }; MyString::MyString(char* pText) { if (pText) { pText_ = new char[ strlen(pText+1) ]; strcpy(pText_, pText); } else { pText_ = new char[1]; *pText_='\0'; } } MyString::MyString(const MyString& str) // Copy-Konstruktor { pText_ = new char[ strlen(str.pText_+1) ]; strcpy(pText_, str.pText_); } MyString& MyString::operator=(const MyString& str) // Zuweisungsoperator { pText_ = new char[ strlen(str.pText_+1) ]; strcpy(pText_, str.pText_); return *this; // Unterschied zum Copy-Konstruktor } inline MyString::~MyString() { delete[] pText_; } void MyString::output() { std::cout << pText_ << std::endl; } void MyString::showaddress() { std::cout << std::endl << std::hex << int(pText_) << ": "; } int main() { MyString str1("hello, world"); MyString str2(str1); // Copy-Konstruktor MyString str3; str3 = str2; // Zuweisungsoperator MyString str4(""); MyString str5; str1.showaddress(); str1.output(); str2.showaddress(); str2.output(); str3.showaddress(); str3.output(); str4.showaddress(); str4.output(); str5.showaddress(); str5.output(); getch(); }
-
#include <stdio.h> #include "Zeile1.hpp" int main() { Zeile z1("\nGuten Tag!\n"); //schließende Klammer fehlte... z1.print(); return 0; }
Liegt es vielleicht daran?
-
Zum Experimentieren (incl. Vererbung):
#include <string> #include <iostream> void wait() // die C++-Alternative von getch() ;) { std::cin.clear(); std::streambuf* pbuf = std::cin.rdbuf(); std::streamsize size = pbuf->in_avail(); std::cin.ignore(size); std::cin.get(); } class Person { private: std::string Vorname; std::string Name; unsigned int Alter; public: ~Person(); Person(); void setVorname(const std::string& value); const std::string& getVorname() const; void setName(const std::string& value); const std::string& getName() const; void setAlter(const unsigned int & value); const unsigned int & getAlter() const; }; const unsigned int & Person::getAlter() const { return Alter; } void Person::setAlter(const unsigned int & value) { Alter = value; } const std::string& Person::getName() const { return Name; } void Person::setName(const std::string& value) { Name = value; } const std::string& Person::getVorname() const { return Vorname; } void Person::setVorname(const std::string& value) { Vorname = value; } Person::Person(){} Person::~Person(){} class Dozent : public Person { private: unsigned int Kurse_noch_geplant; unsigned int Kurse_gehalten; public: void setKurse_noch_geplant(const unsigned int & value); const unsigned int& getKurse_noch_geplant() const; void setKurse_gehalten(const unsigned int & value); const unsigned int& getKurse_gehalten() const; ~Dozent(); Dozent(); }; Dozent::Dozent() : Kurse_gehalten(0), Kurse_noch_geplant(0) {} Dozent::~Dozent(){} const unsigned int & Dozent::getKurse_gehalten() const { return Kurse_gehalten; } void Dozent::setKurse_gehalten(const unsigned int & value) { Kurse_gehalten = value; } const unsigned int & Dozent::getKurse_noch_geplant() const { return Kurse_noch_geplant; } void Dozent::setKurse_noch_geplant(const unsigned int & value) { Kurse_noch_geplant = value; } int main() { Dozent obj; obj.setName("Allwissend"); obj.setVorname("Hugo"); obj.setAlter(85); obj.setKurse_gehalten(13); obj.setKurse_noch_geplant(2); std::cout << obj.getVorname() << " " << obj.getName() << " " << obj.getAlter() << " Jahre alt" << std::endl; std::cout << obj.getKurse_gehalten() << " Kurse schon gehalten." << std::endl; std::cout << obj.getKurse_noch_geplant() << " Kurse noch geplant." << std::endl; wait(); }