über index in der For-Schleife operator<< aufrufen

BLR

Erfahrenes Mitglied
Hallo,

ich habe 3 Kindklassen und eine Elternklasse.
In einem Vector der vom Typ Elternklasse hat ein paar Kindklassen hinzugefügt.

Jede Kindklasse überlädt für sich den Stromausgabeoperator, der als Friend in der jeweiligen h-Datei definiert ist.

Jetzt möchte ich über die for-schleife entsprechende Überladung von der jeweiligen Kindklasse überladen.

Code:

C++:
vector<Auto*> car;
car.push_back(new opel);
car.push_back(new vw);
car.push_back(new audi);

z.B bei der audi.h habe ich den Operator so deklariert:
C++:
friend ostream& operator<<(ostream& os, Audi& au);

Definition:

C++:
ostream& operator<<(ostream& os, Audi& aus){
    os << au.toString() << "\n";

        return os;
}

Aber der Aufruf in der Schleife kriege ich gerade nicht hin:

C++:
for (size_t i = 0; i < devices.size(); i++)
    {
       //hier sollte er nun in die jeweilige Überladung vom Ausgabestromoperator der jeweiligen Kindklasse              //springen
        std::cout << devices.at(i) << "\n";
    }

Leider springt er nicht rein, sondern gibt einfach eine Adresse aus.
Danke für jede Hilfe
 
Hi,

ich glaube das Problem hatte ich auch schonmal...

Hab' mal meine Programme durchforstet und etwas ähnliches gefunden.
Versuchs mal mit "(*devices).at(i)".

Das Problem ist, dass du einen Vector hast der Pointer beinhaltet. Und momentan sagst du deinem std::cout, dass er dir den den Pointer zu i ausgeben soll, also die Speicheradresse.
mit dem (*...) sagst du ihm, dass du dann das Ziel des Pointers, also den Inhalt des Speichers, haben möchtest.

Ich hoffe, dass es schon dein Problem löst. Bitte rückmelden.



//Edit: Es ist etwas umständlich erklärt, ich hoffe du verstehst, was ich sagen möchte^^
 
Zuletzt bearbeitet:
Funktionen kannst du dann übrigens auch so aufrufen:
(*root_ptr).size() (Vector-Funktionen)
(*all_child_messages_ptr) [ i ]->get_subject_of_the_message() (eigene Methode)
 
Zuletzt bearbeitet:
Hallo :)

also dieser Vorschlag kompiliert bei mir nicht mal:

*(devices).at(i) und das auch nicht *(devices.at(i))

Mir ist bewusst, dass ich dereferenzieren soll mit diesem Sternoperator
Durch Polymorphie soll anhand der Elternklasse erkannt werden, welche Kindklasse Überladung aufgerufen werden soll.

Und wenn ich mit der Hilfsvariable arbeite:

C++:
Auto *auto = devices.at(i)
cout << *auto << "\n";

heisst es: Kein "<<"-Operator stimmt mit diesen Operanden überein.
 
Hallo,
ich habe einmal ein funktionierendes Beispiel programmiert. Ich habe dazu außerdem "friend" ersetzt gegen eine virtuelle Funktion. Ich persönlich habe noch nie mit friend gearbeitet und erachte das auch nicht wirklich als sinnvoll (aber jedem das seine).

C++:
#include <iostream>
#include <string>
#include <vector>

class Elternteil
{
public:
    Elternteil() : str("Elternteil") {};
    Elternteil(std::string s) : str(s) {};
    ~Elternteil() {};

    virtual std::string getName() {return str;} ;

private:
    std::string str;
};

std::ostream& operator<<(std::ostream& os, Elternteil *e)
{
    os << e->getName();
    return os;
}

class Kind1 : public Elternteil
{
public:
    Kind1() : str("Kind1") {};
    Kind1(std::string s) : str(s) {};
    ~Kind1() {};

    virtual std::string getName() {return str + std::string("(w)");} ;

private:
    std::string str;
};

class Kind2 : public Elternteil
{
public:
    Kind2() : str("Kind2") {};
    Kind2(std::string s) : str(s) {};
    ~Kind2() {};

    virtual std::string getName() {return str + std::string("(m)");} ;

private:
    std::string str;
};

int main(int argc, char **argv)
{
    std::vector<Elternteil*> vec;
    vec.push_back(new Elternteil("Mama"));
    vec.push_back(new Elternteil("Papa"));
    vec.push_back(new Elternteil());
    vec.push_back(new Kind1("Susanne"));
    vec.push_back(new Kind1());
    vec.push_back(new Kind2("Peter"));
    vec.push_back(new Kind2());

    std::vector<Elternteil*>::iterator it;
    for(it = vec.begin(); it != vec.end(); it++) {
        std::cout << (*it) << std::endl;
    }

    getchar();
    return 0;
}

Beste Grüße,
Jennesta

Edit:

Da du nach Index-Zugriff gefragt hast auch dieser Zugriff:

C++:
for(int i = 0; i < vec.size(); i++) {
     std::cout << vec.at(i) << std::endl;
   }
 
Zuletzt bearbeitet:
Vielen Dank Jannesta,

allerdings sehe ich irgendwie nicht wo du den die Überladung von dem Stromoperator deklariert hast......
Ich sehe nur, dass sie bei dir global ist, weil sie zwei Argumente hat.
Das "friend" bewirkt eigentlich nur, dass diese Methode auf Klassenmember der Klasse zugreifen kann, mehr nicht....
 
Hallo,

der <<-Operator wurde absichtlich nicht in der Klasse definiert, da er logisch nicht wirklich zu der Klasse gehört, sondern eher als Schlüsselfunktion zwischen den Streams und deiner Klasse dient. Ich denke du kannst ihn aber trotzdem einfügen.

Mir ist die Funktionsweise von "friend" durchaus bewusst, jedoch finde ich das im Sinne der Datenkapselung nicht besonders sinnvoll. Daher auch die Implementation über die Klassenmethode "getName()". Der Vorteil hierbei ist durch das Schlüsselwort "virtual" außerdem, dass die richtige Methode automatisch aufgerufen wird. Sollte ein Kind also keine überladene Methode "getName()" besitzen, wird die der Elternklasse aufgrufen.

Grüße,
Jennesta
 
Hello again :)

Hallo :)

also dieser Vorschlag kompiliert bei mir nicht mal:

*(devices).at(i) und das auch nicht *(devices.at(i))

Das * muss in die Klammer :)


Und wenn ich mit der Hilfsvariable arbeite:
C++:
Auto *auto = devices.at(i)
cout << *auto << "\n";

heisst es: Kein "<<"-Operator stimmt mit diesen Operanden überein.

Versuchs mit...
C++:
Auto *auto = (*devices).at(i);
cout << *auto << "\n";

Ob der Aufruf mit dem cout hinhaut bin ich mir auch nicht 100%-ig sicher. Sonst nimm lieber den Weg von Jennesta :D

...im Sinne der Datenkapselung...
 
Übrigens, "auto" ist kein gültiger Variablenname, weil es in C++ schon eine andere Bedeutung hat.
Das reicht für Compilerfehler, auch wenn sonst eigentlich alles richtig ist.
 

Neue Beiträge

Zurück