Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » beliebige Anzahl von Objekten zur Laufzeit - wie?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 < [ 3 ]
010
11.11.2005, 19:00 Uhr
Noob2k5



Ok, ist wirklich kürzer, danke.

Frage 1)
>da std::vector normalerweise gleich 5 objekte alloziiert wenn er initial leer ist

Um nochmal auf den std::vector zurück zu kommen, der holt sich standardmäßig Speicherplatz für 5 Objekte?

Dieser wird auch automatisch wieder zerstört?!

Wenn ich 3 Objekte erzeuge wird der Konstruktor bzw. Destruktor in dieser Reihenfolge aufgerufen:

Konstruktor
Destruktor
Konstruktor
Destruktor
Destruktor
Konstruktor
Destruktor
Destruktor
Destruktor
//Hier werden dann noch die Inhalte des vectors ausgegeben
Destruktor
Destruktor
Destruktor

Also 3x Konstruktor, 9x Destruktor

Mir ist nicht ganz klar anhand welcher Logik der Destruktor aufgerufen wird, der Code den ich oben gepostet hab ist gleich geblieben - sprich ich lösche die von mir erzeugten Objekte nicht! Alle Destruktor aufrufe müssten demnach vom Vector kommen???(Warum soviele?)


Frage 2)
Muss ich zwingend mit dem delete Befehl arbeiten um Objekte zu löschen oder kann ich auch einfach den Konstruktor aufrufen, so z.bmüsste exakt das selbe sein?)
C++:
for(i = 0; i<count;i++)
    {
        konten.at(i).~Konto();
    }


Danke für eure Hilfe, hoffe meinen fragen sind nicht ganz so schlecht formuliert
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
11.11.2005, 21:58 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Wiso willst du denn den Kontruktor immer selbst aufrufen. Mir fällt spontan kein Fall ein in dem dies nötig ist. Lass den Konstruktor einfach selbst arbeiten...

Du könntest z.B. eine Klasse um deine Konten basteln (Kontoverwaltung oder sowas in der Art) die selber einen Destruktor hat der die dir angelegten konnten automatisch löscht....
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
11.11.2005, 22:34 Uhr
Spacelord
Hoffnungsloser Fall


Wenn der vector seine Grösse anpasst kopiert er die Elemente in den neu belegten Speicherplatz und löscht dann die alten Elemente.Dabei wird vector-intern der Destruktor von Konto "benutzt".
Spring mal mit den Debugger in der push_back Codezeile rein.
Ich denke der Code wird dir noch nicht allzuviel sagen aber der entscheidene Part ist dieser hier:


C++:
template<typename _Tp, typename _Alloc>
    void
    vector<_Tp,_Alloc>::
    _M_insert_aux(iterator __position, const _Tp& __x)
    {
      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
      {
        std::_Construct(this->_M_impl._M_finish, *(this->_M_impl._M_finish - 1));
        ++this->_M_impl._M_finish;
        _Tp __x_copy = __x;
        std::copy_backward(__position,
               iterator(this->_M_impl._M_finish-2),
               iterator(this->_M_impl._M_finish-1));
        *__position = __x_copy;
      }
      else
      {
        const size_type __old_size = size();
        const size_type __len = __old_size != 0 ? 2 * __old_size : 1;//Hier wird die neue Groesse des vectors festgelegt(verdoppelt)
        iterator __new_start(this->_M_allocate(__len));
        iterator __new_finish(__new_start);
        try
          {
            __new_finish = std::uninitialized_copy(iterator(this->_M_impl._M_start),
                           __position,
                           __new_start);
            std::_Construct(__new_finish.base(), __x);
            ++__new_finish;
            __new_finish = std::uninitialized_copy(__position,
                           iterator(this->_M_impl._M_finish),
                           __new_finish);
          }
        catch(...)
          {
            std::_Destroy(__new_start,__new_finish);
            _M_deallocate(__new_start.base(),__len);
            __throw_exception_again;
          }
        std::_Destroy(begin(), end());  //Hier kommen deine Destruktor Aufrufe her!
        _M_deallocate(this->_M_impl._M_start,
              this->_M_impl._M_end_of_storage - this->_M_impl._M_start);
        this->_M_impl._M_start = __new_start.base();
        this->_M_impl._M_finish = __new_finish.base();
        this->_M_impl._M_end_of_storage = __new_start.base() + __len;
      }
    }




In dem Beispiel mit den 3 Elementen fängt meine Testversion mit ner Grösse von 0 an.
Dann kommt diese Codepassage:

C++:
const size_type __len = __old_size != 0 ? 2 * __old_size : 1;//


Hier wird die neue Grösse auf 1 festgelegt.Weil es noch keine Elemente zu löschen gibt,gibt es auch keinen Destruktoraufruf.
Beim nächsten Durchlauf muss der vector wieder vergrössert werden.
An der gleichen Stelle wird die neue Grösse jetzt auf 2 festgelegt.
Das eine Element das im vector ist wird in den neuen Speicherbereich kopiert und der alte Speicherbereich wird "freigegeben",wobei der Destruktor des Elements aufgerufen wird.Dann wird das zweite Element in den vector gespeichert.
Beim nächsten Durchlauf wird der vector wieder vergrössert.Diesmal auf 4->die beiden Elemente werden kopiert und dann zerstört-> wieder 2 Destruktoraufrufe.
Dann folgen noch 3 Destruktoraufrufe wenn die Ausführung den Sichtbarkeitsbereich des vectors verlässt.Der vector ist eine Autovariable und wird zerstört.Dabei sorgt der vector dafür dass alle seine Elemente ordnungsgemäss zerstört werden.
Ich komm da also auf 6 Destruktoraufrufe.
Warum du 9 hast musst du mal mit dem Debugger selber untersuchen,aber es wird da vom Prinzip her das Gleiche passieren.Warscheinlich nur irgendwie anders implementiert.

Was die Speicherlöcher angeht.
Speicher den du mit new besorgt hast musst du mit delete wieder freigeben!
In dem Augenblick wo du den Block der Schleife,in der du mit new das Objekt erstellst, verlässt verlierst du den Zeiger auf den Speicherbereich und damit jede Chance den Speicher wieder mit delete freizugeben.Also solltest du entweder das Objekt freigeben nachdem du das Objekt mit push_back in den Vector gesetzt hast(das geht weil der vector ne Kopie macht),oder du speicherst gleich den Kontozeiger im vector und gibst sobald du den vector nicht mehr benötigst mit delete sämtliche Speicherbereiche wieder frei.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
12.11.2005, 17:48 Uhr
Noob2k5



Danke für eure antworten, werd mal gucken warum der Destruktor so oft bei mir aufgrufen wird.


Zitat von Windalf:
noch ne kleine Anmerkung...

C++:
konten.push_back(new konto(count));


dafür musts du dann einfach einen vector von konto-pointern verwenden.... nicht vergessen die am ende auch wieder zu deleten...


Wenn ich das versuche umzusetzten, kommt bei mir folgender Fehler:

Zitat von Compilier:

error C2664: 'std::vector<_Ty>::push_back' : cannot convert parameter 1 from 'Konto *' to 'const Konto &'


Hab das versucht so zu machen:
C++:
int main(int argc, char* argv[])
{    
    int input;
    
    std::vector <Konto> *konten;

    std::cout<<"Bitte geben Sie die Anzahl der zu erzeugenden Objekte an: ";
    std::cin>>input;

    int i;
    for(i=0;i<input;i++)
    {
        
        konten->push_back(new Konto(i));
        
    }


Hab den Konstruktor meiner Konto klasse geändert, das er jetzt einen int wert erwartet um die Kontonummer zu initialisieren.

Dieser Post wurde am 12.11.2005 um 17:50 Uhr von Noob2k5 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
12.11.2005, 20:52 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


mal so schnell dahingekladdert


C++:
//Bank.h
#include <vector>
#include <fstream>

class Konto{

    public:
        Konto(int);
        void SetGuthaben(double);

        int GetKtnr(void);
        double GetGuthaben(void);
        friend std::ostream& operator<<(std::ostream&, Konto&);

    private:
        int ktnr;
        int blz;
        double guthaben;

};


class Bank{
    
    public:
        Bank(int);
        ~Bank();

        void addKonto(int);
        friend std::ostream& operator<<(std::ostream&, Bank&);

    private:

        std::vector<Konto*> kontenliste;
        int blz;

};
#endif




C++:
//Bank.cpp
#include "Bank.h"


Konto::Konto(int _ktnr):ktnr(_ktnr),guthaben(0.0){}

void Konto::SetGuthaben(double guthaben){this->guthaben = guthaben;}

int Konto::GetKtnr(void){return ktnr;}

double Konto::GetGuthaben(){return guthaben;}

std::ostream& operator<<(std::ostream& os, Konto& k){
    os<<"Kontonummer: "<<k.ktnr<<'\t'<<"Guthaben: "<<k.guthaben<<std::endl;
    return os;
}



Bank::Bank(int _blz):blz(_blz){}
Bank::~Bank(){//todo hier deine deletes aufrufen...

}

void Bank::addKonto(int ktnr){kontenliste.push_back(new Konto(ktnr));}

std::ostream& operator<<(std::ostream& os,Bank& b){
    for(size_t i=0;i<b.kontenliste.size();++i)
        os<<*(b.kontenliste[i]);
    return os;
}




C++:
//test.cpp
#include <iostream>
#include "Bank.h"

int main(){    
    
    Bank myBank(4711);
    myBank.addKonto(47110815);
    myBank.addKonto(47111234);
    
    std::cout<<myBank;
}



Das Design und die Implementierung sind noch stark verbesserungswürdig, aber hoffentlich ein Anfang mit dem du weiterarbeiten kannst...
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 12.11.2005 um 20:53 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
14.11.2005, 19:15 Uhr
Noob2k5




Zitat von Windalf:
mal so schnell dahingekladdert


C++:
//Bank.h
#include <vector>
#include <fstream>

class Konto{

    public:
        Konto(int);
        void SetGuthaben(double);

        int GetKtnr(void);
        double GetGuthaben(void);
        friend std::ostream& operator<<(std::ostream&, Konto&);

    private:
        int ktnr;
        int blz;
        double guthaben;

};


class Bank{
    
    public:
        Bank(int);
        ~Bank();

        void addKonto(int);
        friend std::ostream& operator<<(std::ostream&, Bank&);

    private:

        std::vector<Konto*> kontenliste;
        int blz;

};
#endif




C++:
//Bank.cpp
#include "Bank.h"


Konto::Konto(int _ktnr):ktnr(_ktnr),guthaben(0.0){}

void Konto::SetGuthaben(double guthaben){this->guthaben = guthaben;}

int Konto::GetKtnr(void){return ktnr;}

double Konto::GetGuthaben(){return guthaben;}

std::ostream& operator<<(std::ostream& os, Konto& k){
    os<<"Kontonummer: "<<k.ktnr<<'\t'<<"Guthaben: "<<k.guthaben<<std::endl;
    return os;
}



Bank::Bank(int _blz):blz(_blz){}
Bank::~Bank(){//todo hier deine deletes aufrufen...

}

void Bank::addKonto(int ktnr){kontenliste.push_back(new Konto(ktnr));}

std::ostream& operator<<(std::ostream& os,Bank& b){
    for(size_t i=0;i<b.kontenliste.size();++i)
        os<<*(b.kontenliste[i]);
    return os;
}




C++:
//test.cpp
#include <iostream>
#include "Bank.h"

int main(){    
    
    Bank myBank(4711);
    myBank.addKonto(47110815);
    myBank.addKonto(47111234);
    
    std::cout<<myBank;
}



Das Design und die Implementierung sind noch stark verbesserungswürdig, aber hoffentlich ein Anfang mit dem du weiterarbeiten kannst...


danke, übersteigt meinen Horizont noch etwas, muss jetzt erstmal ein paar Kleinigkeiten nach arbeiten
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
21.01.2006, 15:41 Uhr
Noob2k5



Ich muss das Thema nochmal ausbuddeln.

Wie genau muss das aussehen wenn ich Pointer in einem vector speichern möchte:

Ich versuche das derzeit so:


C++:
std::vector<Member> *member;

_____________________________

Member *pMitglied = new Member( id, name, tg, mn, jr);
member.pushback(*pMitglied);



Ich bekomme folgende Fehlermeldung dafür ausgeworfen:


Zitat:

error C2228: left of '.pushback' must have class/struct/union
type is 'std::vector<_Ty> *'
with
[
_Ty=Member
]
did you intend to use '->' instead?


Wirklich schlau werde ich allerdings nicht daraus.

Bin wie immer dankbar für Hilfe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
21.01.2006, 16:39 Uhr
Oliver
S2-Pixelgeneral



C++:
std::vector<Member*> member;

_____________________________

Member *pMitglied = new Member( id, name, tg, mn, jr);
member.pushback(pMitglied);

// Später wieder freigeben!!!
delete pMitlied;


--
Demokratie ist die Diktatur der Mehrheit.

www.siedler25.org/ ( Siedler2 - Remake )
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
21.01.2006, 16:48 Uhr
Spacelord
Hoffnungsloser Fall


Das was du da deklariert hast ist ein Zeiger auf nen std::vector der Member Instanzen aufnimmt,kein vector der Zeiger auf Member Instanzen aufnimmt!

Das was du möchtest sieht so aus

C++:
std::vetor<Member*> my_members;



Das ist ein himmelweiter Unterschied.

Und angenommen der Typ deiner Variablen wäre korrekt,dann würdest du mit deinem pushback Probleme bekommen.
pMitglied ist ein Zeiger auf ne Member Instanz,also das was du eigentlich in den vector stopfen möchtest.
In deinem pushback dereferenzierst du aber den Zeiger und versuchst somit ein Memberobjekt in den vector einzufügen.
Also bei den Problemen die du noch mit Zeigern hast kann ich dir eigentlich nur davon abraten nen vector mit Zeigern zu führen weil du dich um die Speicherfreigabe komplett selber kümmern musst.
Da sehe ich momentan ne Menge Speicherlöcher auf dich zukommen

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
21.01.2006, 16:52 Uhr
Noob2k5



Danke


Zitat von Spacelord:

Also bei den Problemen die du noch mit Zeigern hast kann ich dir eigentlich nur davon abraten nen vector mit Zeigern zu führen weil du dich um die Speicherfreigabe komplett selber kümmern musst.
Da sehe ich momentan ne Menge Speicherlöcher auf dich zukommen

MfG Spacelord


Ich fürchte auch, aber ich sag mir dann immer "das übt" :-)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: