Weitere C++-Fragen (Templates, etc.)

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 06.01.2009 20:21:25

Hallo,

ich habe mal wieder eine Frage zu C++.
Kann mir jemand mal bitte folgenden Code erklären:

Code: Alles auswählen

// Array1.cpp
#include <iostream>
#include <cstdlib>
using namespace std;

template <class T, int n>
class Array {
   private:
   T array[n];
   public:
   int get_size () const {
      return n;
   }
   T& operator[] (int i);
};

template <class T, int n>
T &Array<T, n>::operator[] (int i) {
   if(i < 0 || i >= n ) {
      cout << "Array-Überlauf!!!\n";
      exit(1);
   }
   return array[i];
}

int main( void ) {
   Array<char, 20> str1;
   Array<int, 5> integers;
   
   cout << "Wie heißen Sie: ";
   cin.getline( &str1[0], str1.get_size() );
   cout << "DEBUG " << &str1[0] << " : " << str1[0] << "\n";
   
   cout << "Hallo ";
   for(int i=0; str1[i] != '\0'; i++) {
      cout << str1[i];
   }        
   cout << "\n";
   
   for( int i=0; i < integers.get_size(); i++ ) {
      cout << i+1 << ". Wert: ";
      cin >> integers[i];
   }
   cout << "Die Zahlen die eingegeben wurden ...\n";
   for( int i=0; i < integers.get_size(); i++ ) {
      cout << i+1 << ". Wert: " << integers[i] << "\n";
   }   
   return 0;
}
Und zwar:
1.) Wieso ist hier die Operator-Überladung nötig?
2.) Bei der Tastatureingabe wird das Objekt als &str1[0] angegeben. Wieso muss das &-Zeichen davor? Dies gibt doch normalerweise eine Adresse zurück oder besagt, dass es sich um eine Referenz handelt.
3.) Array<char, 20> str1;
--> hiermit wird doch über den Default-Konstruktor das Objekt str1 aus dem Klassentemplate Array<T> erzeugt.

Und noch die Ausgabe:

Code: Alles auswählen

Wie heißen Sie: Daniel
DEBUG Daniel : D
Hallo Daniel
1. Wert: 2
2. Wert: 4
3. Wert: 3
4. Wert: 22
5. Wert: 11
Die Zahlen die eingegeben wurden ...
1. Wert: 2
2. Wert: 4
3. Wert: 3
4. Wert: 22
5. Wert: 11
Oh, yeah!

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von GoKi » 06.01.2009 20:49:33

Duff hat geschrieben:1.) Wieso ist hier die Operator-Überladung nötig?
Ist nicht nötig. Es erlaubt dir hier aber an die Elemente des Arrays zu kommen. Man muss das nicht über den überladenen operator[] machen. Bspw. gibt es bei der vector<T> Klasse der STL den operator[] zum Zugriff auf ein Element und gleichzeitig auch die Methode at() (Das at() noch mehr tut, ignorieren wir mal).
Duff hat geschrieben:2.) Bei der Tastatureingabe wird das Objekt als &str1[0] angegeben. Wieso muss das &-Zeichen davor? Dies gibt doch normalerweise eine Adresse zurück oder besagt, dass es sich um eine Referenz handelt.
Es liefert einen Pointer (Adresse) auf den Speicher, an dessen Stelle das Array abgelegt ist. Somit kann der Speicher des Arrays überschrieben werden oder der char* ausgegeben werden.
Duff hat geschrieben:3.) Array<char, 20> str1;
--> hiermit wird doch über den Default-Konstruktor das Objekt str1 aus dem Klassentemplate Array<T> erzeugt.
Ja, aber es wird ein Array<T,n> erzeugt :)
MfG GoKi
:wq

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 07.01.2009 09:22:03

GoKi hat geschrieben:
Duff hat geschrieben:1.) Wieso ist hier die Operator-Überladung nötig?
Ist nicht nötig. Es erlaubt dir hier aber an die Elemente des Arrays zu kommen. Man muss das nicht über den überladenen operator[] machen. Bspw. gibt es bei der vector<T> Klasse der STL den operator[] zum Zugriff auf ein Element und gleichzeitig auch die Methode at() (Das at() noch mehr tut, ignorieren wir mal).
Ok, danke.
Das Thema STL kommt jetzt auf den nächsten Seiten ;-)
GoKi hat geschrieben:
Duff hat geschrieben:2.) Bei der Tastatureingabe wird das Objekt als &str1[0] angegeben. Wieso muss das &-Zeichen davor? Dies gibt doch normalerweise eine Adresse zurück oder besagt, dass es sich um eine Referenz handelt.
Es liefert einen Pointer (Adresse) auf den Speicher, an dessen Stelle das Array abgelegt ist. Somit kann der Speicher des Arrays überschrieben werden oder der char* ausgegeben werden.
Sorry, aber ist mir irgendwie noch immer nicht klar.
Ein int& ivar z.B. wäre eine Referenz und ein int* ptr und &ptr wäre doch die Anzeige der Adresse des Pointers ptr und mit *ptr würde ich auf den Wert des Pointer zugreifen (dereferenzieren).
GoKi hat geschrieben:
Duff hat geschrieben:3.) Array<char, 20> str1;
--> hiermit wird doch über den Default-Konstruktor das Objekt str1 aus dem Klassentemplate Array<T> erzeugt.
Ja, aber es wird ein Array<T,n> erzeugt :)
Stimmt, da hast du natürlich recht.
Oh, yeah!

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von GoKi » 07.01.2009 21:10:27

Duff hat geschrieben:Sorry, aber ist mir irgendwie noch immer nicht klar.
Ein int& ivar z.B. wäre eine Referenz und ein int* ptr und &ptr wäre doch die Anzeige der Adresse des Pointers ptr und mit *ptr würde ich auf den Wert des Pointer zugreifen (dereferenzieren).
Du kannst auch z.B. sowas machen

Code: Alles auswählen

int i;
int* ptr = &i;
In deinem Beispiel wird ein Pointer auf das erste Array-Element benutzt, um das komplette Array zu füllen. Es ist ein Workaround, da die Klasse Array, über keine Methode verfügt, die direkt das Array zurückliefert.
Man könnte die Klasse stattdessen erweitern, z.B. so
http://nopaste.debianforum.de/17917
MfG GoKi
:wq

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 08.01.2009 09:23:37

Meine Güte. Immer wenn ich denke, dass ich es nun endlich verstanden habe, verstehe ich auf einmal gar nichts mehr ;-(

Kannst du mir bitte nochmal deine Zeilen Code genau erklären.

- Du nimmst z.B. einen Zeiger auf die Funktion data(). (Warum ist nicht auch ein Zeiger auf array[n], da man bei arrays doch eigentlich immer mit Zeigern arbeitet).
- Bei dem return array wird doch dann nur ein Zeiger auf das erste Element im Array zurückgegeben, oder?
- Bei der DEBUG-Ausgabe benötige ich den void-Zeiger, damit die Adresse ausgegeben wird?

Sorry für die vielen Fragen...
Oh, yeah!

Benutzeravatar
GoKi
Beiträge: 2068
Registriert: 04.07.2003 23:08:56
Lizenz eigener Beiträge: MIT Lizenz

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von GoKi » 08.01.2009 21:23:30

Duff hat geschrieben:Kannst du mir bitte nochmal deine Zeilen Code genau erklären.
Ich kann es zumindest mal versuchen.
Duff hat geschrieben:- Du nimmst z.B. einen Zeiger auf die Funktion data(). (Warum ist nicht auch ein Zeiger auf array[n], da man bei arrays doch eigentlich immer mit Zeigern arbeitet).
Ich habe nirgends einen Zeiger auf eine Funktion benutzt. Die Funktion data() liefert den Zeiger auf das Array zurück. array[n] ist kein Zeiger mehr, sondern das n-te Element im Array ( *(array + n))
Duff hat geschrieben:- Bei dem return array wird doch dann nur ein Zeiger auf das erste Element im Array zurückgegeben, oder?
Ja genau. Aber das Array liegt als ein Block im Speicher. Damit ermöglicht man der Funktion getline() eine gewisse Anzahl von Bytes im Speicher zu überschreiben.
Duff hat geschrieben:- Bei der DEBUG-Ausgabe benötige ich den void-Zeiger, damit die Adresse ausgegeben wird?
Ich caste den Zeiger nach void*, damit die Adresse ausgegeben wird. Andernfalls wird der Ausgabeoperator für char* aufgerufen und die Zeichenkette wird ausgegeben. Das wollte ich in dem Fall jedoch nicht. Dafür gibt es vielleicht auch einen eleganteren Weg...
MfG GoKi
:wq

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 09.01.2009 08:28:30

Ok, danke für die Erklärungen, aber die nächsten Fragen kommen bestimmt bald wieder ....

;-)
Oh, yeah!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 11.01.2009 11:15:35

So, da bin ich wieder mit der nächsten Frage ...


Ich bekomme beim Kompilieren der Datei (es geht um Vectoren) folgende Fehlermeldungen (habe sogar schon extra die Datei von der original-Cd genommen):

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Kapitel05/5.3$ g++ -Wall -o stl_vector stl_vector.cpp.orig 
/usr/bin/ld:stl_vector.cpp.orig: file format not recognized; treating as linker script
/usr/bin/ld:stl_vector.cpp.orig:1: syntax error
collect2: ld returned 1 exit status
Eingebunden habe ich folgendes:

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Kapitel05/5.3$ head -4 stl_vector.cpp.orig
// stl_vector.cpp
#include <vector>
#include <iostream>
using namespace std;
Gruß,
Daniel
Oh, yeah!

Spasswolf
Beiträge: 3472
Registriert: 30.11.2005 10:32:22
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Wald

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Spasswolf » 11.01.2009 11:25:30

Der g++ braucht die richtige Endung für C++:
man g++ hat geschrieben: For any given input file, the file name suffix determines what kind of compilation is done:
[...]
file.cc
file.cp
file.cxx
file.cpp
file.CPP
file.c++
file.C
C++ source code which must be preprocessed. Note that in .cxx, the last two letters must both be literally x. Likewise, .C refers to
a literal capital C.

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 11.01.2009 11:37:26

Oh man.

Danke, hatte ich jetzt nicht so verstanden aber ist irgendwo doch auch in der Fehlermeldung erwähnt.

Naja, dummer Fehler von mir. Vielen Dank, dann kann ich nun weiter experimentieren und das Kapitel STL ein Stückchen weiter bearbeiten ;-)
Oh, yeah!

Benutzeravatar
Meillo
Moderator
Beiträge: 9267
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Meillo » 11.01.2009 11:43:44

Duff hat geschrieben:Meine Güte. Immer wenn ich denke, dass ich es nun endlich verstanden habe, verstehe ich auf einmal gar nichts mehr ;-(
Ein bekanntes Phänomen. Ob das wohl an der unmöglich verstehbaren Komplexität von C++ liegt? :roll:
Gab's da nicht mal jemanden der meinte, C++ kann ein Mensch eigentlich gar nicht voll verstehen. Daher gibt's auch nur 'ne handvoll Menschen die (auch nur) einigermaßen durchsteigen.

Also, alles halb so wild ... du wirst es nie ganz verstehen.

*SCNR*
Use ed once in a while!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 11.01.2009 11:50:09

Sehr aufbauent und sogleich auch ein wenig frusttrierend ;-)

Aber ich habe eh erst die Hälfte des Buches gelesen. Muss also noch ein paar Seiten (ca. 500)...
Oh, yeah!

Benutzeravatar
Duff
Beiträge: 6321
Registriert: 22.03.2005 14:36:03
Wohnort: /home/duff

Re: Weitere C++-Fragen (Templates, etc.)

Beitrag von Duff » 20.01.2009 19:11:05

So, nun bin ich bei meiner nächsten Frage zu C++:
Es geht um die Ein- und Ausgabe und dessen Manipulation mit Hilfe einer Klasse und einem Manipulator:

Code: Alles auswählen

  1 // stream5.cpp
  2 #include <iostream>
  3 #include <iomanip>
  4 using namespace std;
  5 
  6 class ostreamHelp {
  7 private:
  8    int i_;
  9    ostream& (*f_)(ostream&, int);
 10 public:
 11    ostreamHelp(ostream& (*f)(ostream&,int), int i): f_(f),i_(i) {}
 12    friend ostream& operator<<( ostream& os, ostreamHelp m) {
 13       return m.f_(os, m.i_);
 14    }
 15 };
 16 
 17 ostream& myendlHelp( ostream& os, int n ) {
 18    while (os && n--)
 19       os << '\n';
 20    return os;
 21 }
 22 
 23 ostreamHelp myendl( int n ) {
 24    return ostreamHelp( &myendlHelp, n );
 25 }
 26 
 27 int main( int argc, char **argv ) {
 28    cout << "Eine Zeile" << endl;
 29    cout << "Noch eine Zeile ..." << myendl(3);
 30    cout << "... drei Zeilen später ..." << myendl(2);
 31    cout << "... zwei Zeilen später ..." << endl;
 32 
 33    return 0;
 34 }
Und die Ausgabe:

Code: Alles auswählen

daniel@daniel-laptop:~/scripts/C++/Kapitel07/7.2$ ./stream5 
Eine Zeile
Noch eine Zeile ...


... drei Zeilen später ...

... zwei Zeilen später ...
Es wäre schön, wenn mir mal jemand kurz den Ablauf erklären könnte (Objekt ruft...auf, und Zeiger oder Adresse oder Referenz auf...)
Oh, yeah!

Antworten