PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : dynamische 1 dim. Klasse initialisieren



dml
16-04-2009, 09:26
Hi,

ich hab mal wieder ein Problem, dabei geht es aber eher um Grundwissen als um Qt.

Ich möchte ein dynamisches Array initialisieren

class x{
QButtonGroup* revipetype[];
}


x::x{
for( int i=0;i<dynamische variable;i++{
recipetype[i] = new QButtonGroup;
}
}

das klappt ja auch, bloß leider nur lokal

x::methode(){
recipetype[0]->button(0)->text();
// gibt zum Beispiel nix aus, aber beim construktor
}

Doch wie kann ich ein dynamisches Array global initialisieren?

Bedanke mich vielmals für Eure Hilfe! :)
gruß
dml

dml
16-04-2009, 09:41
juti das ist jetzt mal wieder ziemlicher Quatsch von mir,
ich werde es nochmal überarbeiten.

erst überlegen, dann schreiben.

dml
16-04-2009, 10:39
recipetype* QButtonGroup;

recipetype = new QButtonGroup[anz];



Noch früh am Morgen. :D
oder doch zu viel Alkohol gestern. ;)

RHBaum
17-04-2009, 12:52
recipetype* QButtonGroup; // muss das nich QButtonGroup * recipetype heissen ?

recipetype = new QButtonGroup[anz];

Das ist C in C++ schreibweisse Quasi !

Du brauchst die Button-Zeiger am Stueck, also strikt hintereinanderliegend ???
Oder du hasst eine numerische bedeutung der "Position", also z.b. es ist genau definiert welches der 5. ButtonZeiger ist, udn du brauchst sehr schnellen zugriff drauf ?

dann ist besser:


std::vector<QButtonGroup *> myReceiveVector(anz); /// wir wissen wie gross das Array wird ! also ziehen wirs gleich mit der richtigen groesse auf
for(int i = 0; i < anz; ++i) myReceiveVector.push_pack(new QButtonGroup);


Normal merkt man sich im Rest des Programs aber ned die "Positionen" sondern die zeiger direkt, und die dinger muessen ned am Stueck rumliegen, dann eignet sich sowas besser :



std::list<QButtonGroup *> myReceiveList;
for(int i = 0; i < anz; ++i) myReceiveList.push_pack(new QButtonGroup);


Alternativ zu den stl-containern kann man auch die QT container nehmen, ich gewoehn mich aber ungern an standardfunktionalitaet aus 3.d Party Libs/Frameworks

Ciao ...

dml
18-04-2009, 12:02
Cool, vielen dank für Deine Antwort,

ich bin aber mit der Performance recht zufrieden und mit
recipetype = new QButtonGroup[anz]; funktioniert es eigentlich wunderbar.

Dennoch war Deine Antwort sehr Interessant für mich und werd den vector auch brauchen,
wenn ich mal Performance Probleme habe. :rolleyes:

vielen dank! :)

RHBaum
20-04-2009, 10:08
wenn ich mal Performance Probleme habe.
wenn man die groesse vorher weiss, ist dyn. Array vs. vector eigentlich keine frage der Performance. Da sollte sich so gross nix mehr unnerscheiden.

Der vorteil den man von den containern bekommt, ist das einfacherere Exceptionhandling.

stell dir vor:



QWidget ** myArray = new QWidget * [anz];
//// irgend was wildes tun, wir nehmen mal ne einfache funktion foo() an;
foo();
delete[] myArray;


jetzt stell dir vor, in foo kann nen Fehler auftreten, den deine Application abfangen kann / darf ....
nun bau mal das so um, das die exeption fangst, und auch sicherstellst, dass dein Array wieder "bereinigt" wird.

das iss ein vector oder ähnliches einfach pflegeleichter ....

Oft wird in Manuals als der Grosse Vorteil der container oder auto_ptr angepriessen, das man die Dinger ned mehr selber deallocieren muss, es also ned vergessen kann ... das ist aber nur der nebeneffekt (vergessliche Programmierer sind eh ne Gefahr), wichtiger iss die möglichkeit, restrikter aus dem block zwischen allocate und deallocte aussteigen zu koennen, ohne das Memory Leaks entstehen.

Wie gesagt, in c++ sollt man ein T * myArray = new T [x]; nur in sehr sehr seltenen faellen benutzen muessen, es gibt kaum eine entschuldigung da keinen Container zu verwenden.
Nicht zu verwechseln mit einem statischen array (groesse zur compilezeit bekannt).
ein T myStaticArry[100]; hat natürlich immer noch seine performante Daseinsberechtigung, da kommt nen vector ned hinterher.

weiterhin sollt man auch trainieren, die container richtig einzusetzen (vector vs. list vs. dequeue ...). Auch wenn bei dir momentan die Performance ned so wichtig ist, spaeter wird sie es vielleicht mal ! Und man sollt intuitiv schon beim entwerfen des codes den richtigen container nehmen. Schlimmer ist es, spaeter beim optimieren alle container ersetzen zu muessen, bzw ueberhaupt erst mal performance probleme zu haben, die von haus aus umgangen werden könnten.

Ciao ...

dml
20-04-2009, 10:47
Stimmt,
die Möglichkeit der unbestimmten Größe über List, habe ich auch übersehen
und die brauche ich wirklich.

vielen dank! :)

kann ich dann auch noch ohne Probleme


QButtonGroup* buttongroup = new QButtonGroup;
buttongroup = &myReceiveList[i];

achließend noch machen, denn das brauche ich.

RHBaum
20-04-2009, 11:36
bei nem vector kannst das.



std::vector<QButtonGroup*> myVec;
myVec[15] = new QButtonGroup;


das wuerde gehen.
bei dem schreibenden zugriff auf den [] operator, schaut der vector nach, obs das element gibt, wenn nicht, wird es "angelegt" mit allen konsequenzen.

Sprich, der vector wird auf die anz erweitert, fuer alle elemente die die davor "nicht belegt" waren, wird ein element mit dem standard construktor angelegt, aka bei pod typen einfach nen uninitialisiertes element !!!
Was ich als ausserst gefaehrlich erachte !!!
in obigen fall, vorrausgesetzt der vector war vorher leer, werden elemente 1-15 als uninitialisierte zeiger, also zeiger ins nirvana, angelegt, und der 16. dann mit dem Zeiger aufs richtig existierende Object angelegt.

DIe Frage ist, brauchst du wirklich nen vector, und den index zugriff ??? Fuer was ??? Beschreib mal, was genau du noch mit dem zuegs im container machen willst/musst ! Würde es bei dir keine verkettete liste machen ???

Ciao ....

BLUESCREEN3D
20-04-2009, 16:18
bei dem schreibenden zugriff auf den [] operator, schaut der vector nach, obs das element gibt, wenn nicht, wird es "angelegt" mit allen konsequenzen.

Nein, das passiert nur bei std::map.

RHBaum
23-04-2009, 16:32
Ups stimmt, der [] schiesst ungesichert auf den reletiv zum beginn stehenden Zeiger ....
Ich setze den Vector viel zu selten ein ^^

Ciao ...

dml
16-06-2009, 19:27
ein paar Fragen hätte ich aber noch dazu,

Bsp.:

QVector<QHBoxLayout*> vec_hlay;

for(int i=0;i<4;i++){
vec_hlay[i] = new QHBoxLayout;
}


QVector<QLabel*> vec_lab;
for(int i=0;i<12;i++){
vec_lab[i] = new QLabel;
}

vec_lab[1]->setText("eins");
vec_lab[1]->setText("zwei");

vec_hlay[i]->adWidget(vec_lab[1]);
funktioniert, obwohl const?

oder muss ich dann immer replacen, bringt es dann noch etwas?

RHBaum
17-06-2009, 09:50
versteh die frage jetzt nicht ...

Was geht trotz const ?

was musst du replacen ?

Ciao ...

dml
18-06-2009, 07:53
Na, wenn ich den Vector mit Elementen fülle, kann ich dieses nicht mehr ändern, da sie const sein müssen:

void push_back ( const T& x );

Das heisst, jedes mal wenn ich den Inhalt der Elemente ändern möchte muss ich gleich das ganze Element ersetzen, oder?

anda_skoa
18-06-2009, 15:36
Diese Signatur bedeutet lediglich, dass push_back() das Objekt nicht ändern wird.

Wenn du dir die Signatur von operator[] ansiehst, wirst du erkennen, dass es da auch eine Variante mit nicht-konstanter Rückgabe gibt.

Ciao,
_

BLUESCREEN3D
19-06-2009, 15:14
Na, wenn ich den Vector mit Elementen fülle, kann ich dieses nicht mehr ändern, da sie const sein müssen:

void push_back ( const T& x );


Diese Signatur bedeutet lediglich, dass push_back() das Objekt nicht ändern wird.

Wichtig ist dabei, dass push_back() zwar das Objekt als const Referenz übergeben kriegt, intern dann aber eine Kopie davon in den vector packt. Und diese Kopie darf verändert werden, da sie nicht const ist.
Du darfst also von dem Typ des Parameters von push_back() nicht auf den intern gespeicherten Typ schließen.

dml
29-06-2009, 19:01
ist doch ganz logisch :)
da soll doch noch einmal jemand sagen das c++ kompliziert ist. ;)

mal wieder ein herzliches Dankeschön an mrunix und seine Comunity!