Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: C++ vraag  (gelezen 5543 keer)

C++ vraag
« Gepost op: 2008/06/07, 17:38:23 »
Hallo,

ik heb een paar problemen met het programmeren in C++. In java kan je vb doen:

Object o;
//...
o = new Object();
Nu wil ik in C++ doen:

QWidget * q;
//...
q = new QWidget;
maar dan krijg ik de volgende foutmelding:

src/globals.h:7: error: expected constructor, destructor, or type conversion before '=' tokenIk gebruik de volgende versies van software:
Citaat
gcc: i686-apple-darwin9-gcc-4.0.1
make: GNU Make 3.81, i386-apple-darwin9.0
qmake: QMake version 2.01a
qdevelop: version 0.25
Als het nodig is, kan ik de code van het gehele programma uploaden.

Alvast bedankt,

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline profoX

  • Lid
    • wesley
    • Lionslink
C++ vraag
« Reactie #1 Gepost op: 2008/06/07, 17:44:11 »
Ik zie niet echt iets fout daar, maar inderdaad lijkt het me beter als je het in zijn context plaatst, dus het hele programma.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

C++ vraag
« Reactie #2 Gepost op: 2008/06/07, 18:59:46 »
Je kan de code hier downloaden:

http://www.megafileupload.com/en/file/68483/syrpmbuild-zip.html

De bestanden die van belang zijn, zijn globals.h en globals.cpp, in Globals.h declareer ik Configuration * CONFIG; en in globals.cpp declareer ik CONFIG = new Configuration;

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline profoX

  • Lid
    • wesley
    • Lionslink
C++ vraag
« Reactie #3 Gepost op: 2008/06/07, 20:35:18 »
Als je globals.h include heb je misschien wel die CONFIG variabele, maar daar is dan niets aan toegewezen. Het is niet zo dat die .cpp file zomaar wordt uitgevoerd. Om een globale configuration class te hebben zou je eventueel een Singleton kunnen gebruiken (of een static class indien je geen slots e.d. nodig hebt, maar die wil je wel hebben)... of je herziet de structuur van je programma wat en maakt ergens in het begin (bv. in je main of core class) een Configuration object aan, die je dan eventueel doorgeeft aan de constructor van objecten zoals QMetaBar..

Andere opmerkingen:

* wist je dat dit appje meer dan 500 MB ram in beslag neemt tijdens het compileren door die reuzegrote opsomming bij die QStringList? :P Ik zou die dingen eerder uitlezen vanuit een tekstbestand ofzo
* als je iets inpakt zou ik dat in een aparte map doen, want nu deed ik 'unzip file.zip' en kwamen er allemaal losse bestanden in de map waar ik het uitpakte, dat was een beetje vervelend want dan moest ik ze allemaal afzonderlijk verwijderen
* als je objecten op de heap aanmaakt, zorg er dan ook voor dat die objecten allemaal gedeleted worden, bij Qt gebeurt dit inderdaad grotendeels automatisch, maar alleen als je de objecten een parent geeft

edit: ik ga ervan uit dat jij zelf wel zult/kunt googlen naar de zaken die ik heb opgenoemd, maar als je wat extra uitleg wil vraag je het maar hé, hoewel ik zelf natuurlijk ook geen expert C++/Qt ben.. het IRC kanaal #qt op irc.freenode.net en www.qtcentre.org zijn wel handige hulpmiddelen om hulp te vragen vind ik
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

C++ vraag
« Reactie #4 Gepost op: 2008/06/08, 11:48:53 »
Hallo,

Ik heb het volgende al geprobeerd:

globals.h:
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
#include "configuration.h"

class Global {
public:
static Configuration * CONFIG;
};
#endif
globals.cpp:
#include "globals.h"

Global::CONFIG = new Configuration;
Maar dan krijg ik dezelfde fout.

Over jou opmerkingen:
* Ik heb hier 2 GB ram, ik merk dat dus nog eens niet :P. Ik heb proberen uit te zoeken hoe ik iets van een tekstbestand kan lezen, maar er is geen goede manier om dat cross-platform te doen. Op Mac OS X zou ik bv. het tekstbestand willen halen uit de map "Resources", terwijl in Linux ik het zou willen halen uit "$dataroot/syrpmbuild" (dataroot is meestal /usr/share, maar dit kan normaal gezien veranderd worden)
* Sorry, meestal doe ik dit wel, maar ik had het snel ingepakt deze keer. Rechtsklikken -> inpakken als...
* Worden die objecten niet automatisch vewijderd als je het programma afsluit?

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline profoX

  • Lid
    • wesley
    • Lionslink
C++ vraag
« Reactie #5 Gepost op: 2008/06/08, 12:29:51 »
Citaat van: SeySayux
Ik heb het volgende al geprobeerd:

globals.h:
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
#include "configuration.h"

class Global {
public:
static Configuration * CONFIG;
};
#endif
globals.cpp:
#include "globals.h"

Global::CONFIG = new Configuration;
Maar dan krijg ik dezelfde fout.
Ik zou iets op bv. deze manier doen:

verandering aan configuration.h
void setName(const QString & name);verandering aan configuration.cpp
void Configuration::setName(const QString & name) {
this->setName(name);
}
[ edit: ik zie nu pas dat deze functie setName() eigenlijk niet kan kloppen... je zal gewoon recursief iets blijven uitvoeren; ik had zelf ook een heap/stack foutje gemaakt in main.cpp hieronder, heb ik even aangepast ]

globals.h
#ifndef __GLOBALS_H__
#define __GLOBALS_H__
//#include "configuration.h"

class Configuration;
class Global {
public:
Global();
~Global();
Configuration * config;
};
#endif // __GLOBALS_H__
globals.cpp
#include "globals.h"
#include "configuration.h"

Global::Global() {
config = new Configuration;
}

Global::~Global() {
delete config;
}
verandering aan main.cpp
void initialize(QWidget * win)
{
Global * global = new Global;

win->setMinimumSize(640,480);
QVBoxLayout *layout = new QVBoxLayout;

QTabWidget * tabbar = new QTabWidget;
layout->addWidget(tabbar);

MetaTab * meta = new MetaTab(0, &global);
tabbar->addTab(meta, QObject::tr("Meta"));

QWidget * prep = new QWidget;
tabbar->addTab(prep, QObject::tr("Prep Section"));
// etc...
verandering aan metatab.cpp
//valueChanged
connect(name, SIGNAL(textChanged(const QString &)), global->config, SLOT(setName(const QString &)));
Maar eigenlijk zit de code wat messy in elkaar. Ik zou eens een goed boek over C++ aanschaffen. Eentje die je ook 'design patterns' (ontwerppatronen) aanleert. Ook helpt het wel om de voorbeeldcode van bv. Qt 4 demos/examples te bekijken. Die zijn altijd heel netjes geprogrammeerd.

Voor de GUI zou je btw Designer kunnen gebruiken in plaats van het handmatig te hoeven doen.
Zodat je dit soort gekke dingen niet doet:
QScrollArea * scroller = new QScrollArea(this);
scroller->setWidget(this);
Bij mij gebruikt dit gewoon 100% CPU zonder iets nuttigs te doen.

Citaat van: SeySayux
* Ik heb hier 2 GB ram, ik merk dat dus nog eens niet :P. Ik heb proberen uit te zoeken hoe ik iets van een tekstbestand kan lezen, maar er is geen goede manier om dat cross-platform te doen. Op Mac OS X zou ik bv. het tekstbestand willen halen uit de map "Resources", terwijl in Linux ik het zou willen halen uit "$dataroot/syrpmbuild" (dataroot is meestal /usr/share, maar dit kan normaal gezien veranderd worden)
Als je op verschillende OS'en verschillende mappen wil gebruiken zou je platform defines kunnen gebruiken: Q_WS_X11 voor Linux, Q_WS_WIN voor Windows, Q_WS_MAC voor Mac (en Q_WS_QWS voor Qtopia Core) bv.:

#ifdef Q_WS_X11
resPath = "/usr/share/syrpmbuild/"
#else
resPath = "Resources/"
#endif

Een andere mogelijkheid is volgens mij om de static function QDir::setSearchPaths te gebruiken om in te stellen in welke mappen gezocht moet worden: http://doc.trolltech.com/4.4/qdir.html#setSearchPaths

Citaat van: SeySayux
* Worden die objecten niet automatisch vewijderd als je het programma afsluit?
Bij alle moderne besturingssystemen wel, maar dat is geen reden om niet netjes te programmeren :P In het midden van een programma zou zoiets gemakkelijk kunnen uitmonden in de befaamde 'memleaks' of geheugenlekken. Eigenlijk geldt: voor elke "new" heb je een "delete" nodig op de gepaste plaats, maar bij Qt objecten volstaat het meestal als je bij het aanmaken van het object een parent meegeeft, wanneer die parent dan wordt gedeleted, worden ook automatisch alle 'child' objecten van die parent gedeleted.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

C++ vraag
« Reactie #6 Gepost op: 2008/06/08, 13:26:01 »
wat jij zegt dat ik moet veranderen aan configuration.h/cpp heb ik toch al? Is er ook een manier waarmee ik gemakkelijker/beter de gegevens die op alle tabbladen aangeduid zijn door de gebruiker zijn ingevoerd bijeen te krijgen zodat deze verwerkt kunnen worden? En ik heb toch ongeveer dezelfde stijl gebruikt als die ze gebruikten in de Qt-tutorial? Ik zal de voorbeeld-code bekijken.

En mensen die van mening verschillen of het beter is om
void test (int i)
{
dummy();
}
of
void test (int i) {
dummy();
}
te gebruiken, begrijp ik niet hoor...

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline profoX

  • Lid
    • wesley
    • Lionslink
C++ vraag
« Reactie #7 Gepost op: 2008/06/08, 13:37:48 »
Citaat van: SeySayux
wat jij zegt dat ik moet veranderen aan configuration.h/cpp heb ik toch al?
Ik heb er 'const' bijgezet zodat de types in de connection overeenkomen:
textChanged(const QString &) is het signaal dat van QLineEdit komt.
Ik denk dat je daaroorspronkelijk gewoon QString & had staan.... en dan zou je deze run-time error krijgen:
Object::connect: No such signal QLineEdit::textChanged(QString&)

Citaat van: SeySayux
Is er ook een manier waarmee ik gemakkelijker/beter de gegevens die op alle tabbladen aangeduid zijn door de gebruiker zijn ingevoerd bijeen te krijgen zodat deze verwerkt kunnen worden? En ik heb toch ongeveer dezelfde stijl gebruikt als die ze gebruikten in de Qt-tutorial? Ik zal de voorbeeld-code bekijken.
Als ik het goed begrijp wil je die gegevens die daar zijn ingevuld verwerken bij het klikken op één van die knoppen?
Dan zou je dat rechtstreeks kunnen verwerken vanuit de GUI velden zelf.

Citaat van: SeySayux
En mensen die van mening verschillen of het beter is om
void test (int i)
{
dummy();
}
of
void test (int i) {
dummy();
}
te gebruiken, begrijp ik niet hoor...
Wie zegt zoiets? Dat is allebei hetzelfde.
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)

C++ vraag
« Reactie #8 Gepost op: 2008/06/08, 14:18:54 »
Hoe moet ik dan vanuit een andere klasse aan de pointers naar deze widgets komen? En door ze door te geven aan de constructor...
Builder::Builder(QLabel * name, QLabel * url QLabel * version /* reken hier nog een 500-tal andere wigdets bij */ , QCheckBox actuallyBuild) {
}
Ik denk niet dat dat gaat lukken ;).

En hoe moet ik dan eenvoudig gegevens inladen? Ook door de QWidget::setSomething(QString * q const) calls?

Bedankt dat je me wilt helpen,

- SeySayux
I use a Unix-based system, that means I'll get laid as often as I have to reboot.
LibSylph
SeySayux.net

Offline profoX

  • Lid
    • wesley
    • Lionslink
C++ vraag
« Reactie #9 Gepost op: 2008/06/08, 14:34:27 »
Ik wist niet dat je vanuit een andere klasse wou werken...
Je kan natuurlijk dat config object wel gebruiken als je wil.
Alleen moet zoiets dan wel anders:
void Configuration::setName(const QString & name) {
    this->setName(name);
}
je wil wellicht zoiets:
void Configuration::setName(const QString & name) {
    _name = name;
}
waarbij _name een public variabele is (of: _name is een private variabele en een public functie "const QString & getName() {return _name;};"
Human Knowledge Belongs To The World -- Antitrust (2001)
Nederlandstalige Ubuntu documentatie van Ubuntu-NL (wiki)