[c++] classes

Pagina: 1
Acties:

  • Vinzzz243
  • Registratie: Februari 2001
  • Laatst online: 22-01-2025
Ondanks vele topics hierover en echt dagen zoeken op internet kom ik er maar niet uit.

Het probleem is (denk ik) simpel...Ik moet een aantal classes maken in cbuilder6 die met elkaar communiceren met wat operaties. Maar om er uit te komen zal ik toch eerst met 1 class moeten kunnen "goochelen", uitzoeken hoe alles werkt (attributen veranderen en default waardes enzo geven)... maar het wil maar niet lukken.

Een simpel voorbeeldje:
unit1.h
code:
1
2
3
4
5
6
7
8
9
10
class MyClass
{
    private:
    public:
    int myInt;
    MyClass()
    {
        myInt = 0;
    }
};

unit1.cpp
code:
1
2
3
4
5
MyClass *MijnClass;

en onder een buttonclick
if (MijnClass->myInt==0) Edit1->Text='0';
  else Edit1->Text='1';


Wanneer ik nu run krijg ik steeds Acces Violation. Het zal vast en zeker wat te maken hebben met geheugen en dit vrijmaken voor de class ofzo, maar ik kom er echt niet uit. Heb al vele dingen toegevoegd, weggehaald (voor de classdefinitie: class MyClass;) maar wil maar niet lukken

Verwijderd

Je heb een pointer naar MyClass, maar die pointer heb je nog niet geinitialiseerd.
Dit doe je door 'new'.

Oftewel:
code:
1
MijnClass = new MyClass();


Wat je ook kan doen ipv:
code:
1
2
MyClass *MijnClass;
MijnClass = new MyClass();

is dit:
code:
1
MyClass *MijnClass = new MyClass();

[ Voor 49% gewijzigd door Verwijderd op 22-11-2002 11:18 ]


  • Vinzzz243
  • Registratie: Februari 2001
  • Laatst online: 22-01-2025
Deze levert foutmelding: Type name expected, multiple declaration for 'MijnClass' en earlier declaration of 'MijnClass'
code:
1
2
MyClass *MijnClass;
MijnClass = new MyClass();


terwijl deze PERFECT werkt!
code:
1
MyClass *MijnClass = new MyClass();


enig idee hoe dit kan?

Verwijderd

edit:
Foute code

[ Voor 116% gewijzigd door Verwijderd op 22-11-2002 11:47 ]


Verwijderd

Verwijderd schreef op 22 november 2002 @ 11:40:
Ik heb hier geen cbuilder, maar het moet waarschijnlijk zo:
code:
1
2
MyClass *MijnClass;
*Mijnclass = new MyClass();
Dit gaat zeker niet werken...!

  • Vinzzz243
  • Registratie: Februari 2001
  • Laatst online: 22-01-2025
nope :( multiple declaration blablabla...
Maar goed, het werkt iig geval met die ene regel code.
Kan iemand me vertellen of en zoja waarom het echt noodzakelijk is, om vóór mijn classdefinitie nog een regel class MyClass; toe te voegen??

edit:
infinity was me al voor :)

[ Voor 9% gewijzigd door Vinzzz243 op 22-11-2002 11:45 ]


Verwijderd

Vinzzz schreef op 22 november 2002 @ 11:26:
Deze levert foutmelding: Type name expected, multiple declaration for 'MijnClass' en earlier declaration of 'MijnClass'
code:
1
2
MyClass *MijnClass;
MijnClass = new MyClass();


terwijl deze PERFECT werkt!
code:
1
MyClass *MijnClass = new MyClass();


enig idee hoe dit kan?
Ik denk dat je includes dan niet goed gaan....
Moet je eff kijken of dat wel goed staat....

  • whoami
  • Registratie: December 2000
  • Nu online
Verwijderd schreef op 22 November 2002 @ 11:40:
Ik heb hier geen cbuilder, maar het moet waarschijnlijk zo:
code:
1
2
MyClass *MijnClass;
*Mijnclass = new MyClass();


Misschien eerst even zeker weten of eens opzoeken. Dit is verkeerd.

https://fgheysels.github.io/


Verwijderd

Verwijderd schreef op 22 november 2002 @ 11:43:
[...]


Dit gaat zeker niet werken...!
Oh, ok. Ik vergeet altijd hoe het moet in c++ :)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Nee, nee, nee.

Het is simpelweg MyClass MyObject; en dan MyObject. ipv ->

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

zorg dat je in class header het volgende hebt:

#infdef MIJNCLASS_H
#define MIJNCLASS_H

//jouw class declaratie

#endif

  • whoami
  • Registratie: December 2000
  • Nu online
Verwijderd schreef op 22 november 2002 @ 11:45:
[...]


Ik denk dat je includes dan niet goed gaan....
Moet je eff kijken of dat wel goed staat....


Volgens mij heeft het niets met includes te maken.
Als je een multiple declaration error krijg, wil dit gewoon zeggen dat je die variable meerdere keren gedeclareerd hebt.
De topicstarter zal dus meerdere keren:
code:
1
MyClass* MijnClass;

in zijn code staan hebben.

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Nu online
MSalters schreef op 22 november 2002 @ 11:46:
Nee, nee, nee.

Het is simpelweg MyClass MyObject; en dan MyObject. ipv ->

Ja, dat kan je doen.
Maar in C++ Builder moeten alle objecten die je instantieert van classes die een relatie hebben met de VCL op de heap gecreeërd worden.

https://fgheysels.github.io/


  • Vinzzz243
  • Registratie: Februari 2001
  • Laatst online: 22-01-2025
Verwijderd schreef op 22 November 2002 @ 11:47:
zorg dat je in class header het volgende hebt:

#infdef MIJNCLASS_H
#define MIJNCLASS_H

//jouw class declaratie

#endif
dat had ik
De topicstarter zal dus meerdere keren:
code:
1
MyClass* MijnClass;
ook niet :D...

We moeten echt werken met -> geen '.'

[ Voor 5% gewijzigd door Vinzzz243 op 22-11-2002 11:54 ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

code:
1
2
3
MyClass *PointerToInstance;

PointerToInstance = new MyClass ();

De new operator geeft een geheugenadres terug, niet de instantie zelf. Vandaar ook dat je een Pointer naar een instantie declareert, en niet een instantie zoals:
code:
1
MyClass Instance ();

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • Vinzzz243
  • Registratie: Februari 2001
  • Laatst online: 22-01-2025
ja dit begrijp ik. Hoewel het standaard op duizenden sites staat op deze manier, werkt hij bij mij niet. Terwijl MyClass *PointerToInstance = new MyClass(); wel werkt

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Het gaat fout als je na MyClass *MyObject een , tikt in plaats van een ;

Dan heb je MyClass *MyObject, MyObject = new MyClass() ; wat een poging is om een MyClass pointer en een MyClass object te declareren die allebei MyObject heten.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Vinzzz243
  • Registratie: Februari 2001
  • Laatst online: 22-01-2025
MSalters schreef op 22 November 2002 @ 12:15:
Het gaat fout als je na MyClass *MyObject een , tikt in plaats van een ;

Dan heb je MyClass *MyObject, MyObject = new MyClass() ; wat een poging is om een MyClass pointer en een MyClass object te declareren die allebei MyObject heten.
ja maar zo 8)7 was ik niet op het moment van dat in te kloppen :D

Verwijderd

Vinzzz schreef op 22 november 2002 @ 11:12:
Het probleem is (denk ik) simpel...Ik moet een aantal classes maken in cbuilder6 die met elkaar communiceren met wat operaties. Maar om er uit te komen zal ik toch eerst met 1 class moeten kunnen "goochelen", uitzoeken hoe alles werkt (attributen veranderen en default waardes enzo geven)... maar het wil maar niet lukken.
Bedenk eerst wat voor classes je nodig denkt te hebben, bedenk de interfaces die ze dienen te hebben en begin dan pas met implementeren.
Als je dus een integer-waarde uit een class wilt halen, dan moet je daar dus een interface voor schrijven. Ik zou je ten zeerste afraden om de datamembers publiek toegankelijk te maken.
Ook de initialisatie van datamembers kun je beter anders doen, en snap ik niet waarom je een pointer initialiseert i.p.v. een object instantieert.

Ik zou dan dus hel volgende coderen:
Classe-definitie, (met implementatie inline-d)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MyClass {
private:
    int m_Value;
public:
    MyClass(int init = 0) //default constructor
        :m_Value(init)
    { };

    MyClass(const MyClass& obj) // copy constructor
        :m_Value(obj.m_Value)
    { };

    virtual ~MyClass() { }; // destructor

// modifiers:
    MyClass& operator=(const MyClass& obj) // assignment operator
    {
        if (&obj != this)
            m_Value = obj.m_Value;
        return *this;
    }

// selectors:
    int getIntegerValue() const { return m_Value; };

}

Gebruik van de class in code:
C++:
1
MyClass MijnClass;

en onder een buttonclick:
C++:
1
 Edit1->Text = (MijnClass.getIntegerValue())?'1':'0';

[ Voor 20% gewijzigd door Verwijderd op 22-11-2002 13:52 . Reden: assignment operator toegevoegd ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

whoami schreef op 22 November 2002 @ 11:49:

[...]

Ja, dat kan je doen.
Maar in C++ Builder moeten alle objecten die je instantieert van classes die een relatie hebben met de VCL op de heap gecreeërd worden.
True, maar ik zie persoonlijk in de definitie van MyClass nergens een ancestor staan, laat staan TObject :z

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 22 November 2002 @ 11:46:
Nee, nee, nee.

Het is simpelweg MyClass MyObject; en dan MyObject. ipv ->
Errug onzinning om dit als 'gouden regel' te presenteren. Tis maar compleet afhankelijk van de toepassing of je op de stack of op de heap instantieert, allebei zijn ze op volkomen andere momenten nodig.

Professionele website nodig?


Verwijderd

Ik ben het met curry eens. Houd er ook rekening mee dat als je geen pointers gebruikt om het object door te geven in functies je misschien een copyconstructor moet implementeren (|:( vergeet ik nog wel eens en is een zeer storende bron van fouten).

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
curry684 schreef op 22 november 2002 @ 13:50:
[...]

Errug onzinning om dit als 'gouden regel' te presenteren. Tis maar compleet afhankelijk van de toepassing of je op de stack of op de heap instantieert, allebei zijn ze op volkomen andere momenten nodig.
Ik merk dat ik steeds minder objecten op de heap zet (anders dan via STL containers ). Dat komt omdat ik steeds meer exceptions gebruik, en je stack wel netjes wordt opgeruimd. Om dezelfde reden gebruik ik vrijwel helemaal geen delete meer buiten destructors; heap objecten zijn functioneel gezien bij mij members van andere objecten.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Verwijderd schreef op 22 november 2002 @ 19:43:
Ik ben het met curry eens. Houd er ook rekening mee dat als je geen pointers gebruikt om het object door te geven in functies je misschien een copyconstructor moet implementeren.
Vind ik zowiezo moeten: default contructor, copy constructor, destructor assignment operator. Die moet je standaard implementeren, en bij de assignment operator jezelf aanleren op te controlleren op "&obj == this"... Nooit jezelf overleveren aan de genade van een C++ compiler, die bedriegt je waar je bij staat...

  • AaroN
  • Registratie: Februari 2001
  • Laatst online: 16-08-2023

AaroN

JayGTeam (213177)

Nog een klein puntje, maar cker wel belangrijk:
De Topicstarter, geeft de implementatie van zijn class in de Header - file. De headeer file is slechts bedoeld voor Interfaces en definities van constanten. De implementatie van de class hoort volgens mij in een CPP - source file.

JayGTeam (213177)


Verwijderd

Vind ik ook (ondanks mijn bovenstaande voorbeeld, wou echter ruimte besparen en in zijn lijn volgen). Ik geef er de voorkeur aan om de interface van een class in de header file te defineren, de inline implementatie in een ".inl" file die aan het eide van de headerfile wordt geinclude, en de "gewone" implementatie in de source-file.
Interface: .hh .hpp .hxx
implementatie: .cc .cpp .cxx
inline implementatie: .icc .inl

[ Voor 17% gewijzigd door Verwijderd op 26-11-2002 11:23 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 26 november 2002 @ 10:55:
[...]

Vind ik zowiezo moeten: default contructor, copy constructor, destructor assignment operator. Die moet je standaard implementeren, en bij de assignment operator jezelf aanleren op te controlleren op "&obj == this"... Nooit jezelf overleveren aan de genade van een C++ compiler, die bedriegt je waar je bij staat...
Fout, IMO.

Ten eerste hoef je in je default assignment operator niet te controleren op this==&rhs. Een assignment die dat nodig heeft, is niet exception safe. Een assignment die exception-safe is, werkt ook als this==&rhs.

vb. canonieke operator=
Foo& Foo::operator=( Foo const& rhs )
{
Foo tmp( rhs );
this->swap( tmp );
return *this;
}
Als rhs==this, dan swap je twee identieke objecten.

Ten tweede is het absoluut overbodig om een copy ctor te implementeren, als een kopie simpelweg een memberwise copy is. De kans dat de compiler dat fout doet, is vele malen kleiner dan de kans dat jij dat fout doet. Je bedriegt alleen jezelf.

Bovendien suggereer je door die copy ctor wel te implementeren, dat deze afwijkt van de default.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

MSalters schreef op 26 November 2002 @ 12:41:
Ten eerste hoef je in je default assignment operator niet te controleren op this==&rhs. Een assignment die dat nodig heeft, is niet exception safe. Een assignment die exception-safe is, werkt ook als this==&rhs.
Maar zodra je dynamisch alloceerbaar geheugen gebruikt, gaat het al snel fout. Dan moet je namelijk het oorspronkelijk gealloceerde geheugen verwijderen en dat gaat dan fout...

voorbeeld (uit "Eff. C++: Item 11"):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class MyString {
private:
    char *data;

public:
    MyString(const *data) {
       if (data)
       {
            data = new char [strlen(value)+1];
            strcpy(data,value);
        } else {
            data = new char[1];
            *data = '\0'
    }

    ~MyString() {
        delete [] data;
    }
}

[...]
{
    [...]
    MyString a("Hello");
    {
        MyString b("World");
        a = b;
    } // Uh O!!
Ten tweede is het absoluut overbodig om een copy ctor te implementeren, als een kopie simpelweg een memberwise copy is. De kans dat de compiler dat fout doet, is vele malen kleiner dan de kans dat jij dat fout doet.
Dat gaat dus vaak niet op met gebruik van dynamisch gealloceerd geheugen, of met objecten met unieke ID's (records, lijsten ed: database gerelateerd, waar C++ het meeste voor ingezet wordt).
Het is inderdaad niet altijd nodig zelf te schrijven, maar de kans dat je het zelf fout doet als je gestructureerd te werk met gaat is ook niet echt groot.

[ Voor 33% gewijzigd door Verwijderd op 28-11-2002 10:16 ]


Verwijderd

Verwijderd schreef op 26 november 2002 @ 13:36:
O, dat denk jij? Dat gaat dus direct fout met gebruik van dynamisch gealloceerd geheugen, of met objecten met unieke ID's (records, lijsten ed: database gerelateerd, waar C++ het meeste voor ingezet wordt).
Een beetje beter lezen kan geen kwaad: Hij had het over memberwise copy. Dit is precies wat een door de compiler gegenereerde copy ctor doet. Als dit alles is wat je nodig hebt, is het beter om dat aan de compiler over te laten. De kans dat die iets over het hoofd ziet is toch wat kleiner dan dat jij dat doet. Als je bijv. later een member toevoegt, worden de door de compiler gegenereerde copy ctor en operator= automatisch aangepast, terwijl jij nog even met de hand kopietjes moet maken...
Het is het /heel/ verstandig zelf iets te schrijven, want de kans dat de compiler dat fout doet, is vele malen groter dan de kans dat ik dat fout doe. En dat geld voor de meeste (betere) C++ programmeurs.
IMHO geldt voor de meeste (betere) C++ programmeurs dat ze weten wanneer ze iets zelf moeten doen en wanneer ze dat aan de compiler over moeten laten. Ken uw compiler...

Verwijderd

Verwijderd schreef op 26 november 2002 @ 14:28:
Een beetje beter lezen kan geen kwaad: Hij had het over memberwise copy. Dit is precies wat een door de compiler gegenereerde copy ctor doet. Als dit alles is wat je nodig hebt, is het beter om dat aan de compiler over te laten. De kans dat die iets over het hoofd ziet is toch wat kleiner dan dat jij dat doet. Als je bijv. later een member toevoegt, worden de door de compiler gegenereerde copy ctor en operator= automatisch aangepast, terwijl jij nog even met de hand kopietjes moet maken...
IMHO geldt voor de meeste (betere) C++ programmeurs dat ze weten wanneer ze iets zelf moeten doen en wanneer ze dat aan de compiler over moeten laten. Ken uw compiler...
edit:
Toen ik c++ moest leren moest ik er rekening mee houden dat compilers (mogelijkerwijs) bitwise-copy's gingen uitvoeren als je geen copy ctor schreef. daar ben ik in blijven hangen, in de veronderstelling dat het nog altijd niet zo rooskleurig is gesteld. Ik ben maar eens met de huidige compilers gaan praten... Ze zijn wat veranderd. |:(
Ben teveel op de stl (van gcc) gefocussed geweest.

[ Voor 30% gewijzigd door Verwijderd op 28-11-2002 10:23 ]


Verwijderd

Verwijderd schreef op 26 November 2002 @ 14:40:
Leuk, ik ontwikkel mee aan de GCC C++ compiler...
Dan moet je ook weten dat een C++ compiler default constructors en default assignment-operators mag wegoptimaliseren. Op het moment dat je deze default-members overschrijft met eigen versies kan/mag de compiler deze optimalisaties niet meer doen. Reden te meer om ze niet te overschrijven als het niet nodig is.

Verwijderd

Verwijderd schreef op 26 november 2002 @ 14:40:
Die kunnen echt niet ruiken of een bitwise-copie gerechtvaardigd is. Ken uw code, kun je dan beter zeggen: of d'r een bitwise verhouding is.
Dat is precies mijn punt: jij moet weten wanneer het nodig is om er zelf een te schrijven. Als je weet dat het niet nodig is, kan je het rustig aan de compiler overlaten.
Maar dan moet je ook de class-definities van alle onderliggende members kennen.
Dat hoeft niet. Een impliciet gegenereerde copy ctor maakt gebruik van de copy ctors van z'n subobjects.

[ Voor 3% gewijzigd door Verwijderd op 26-11-2002 15:12 . Reden: quotes gecorrigeerd... ]


Verwijderd

Verwijderd schreef op 26 November 2002 @ 15:07:
Dat hoeft niet. Een impliciet gegenereerde copy ctor maakt gebruik van de copy ctors van z'n subobjects.
FOUT! Een impliciet gegenereerde copy ctor is toch niks anders dan een 1-op-1 mem-copy!

[ Voor 4% gewijzigd door Verwijderd op 28-11-2002 10:24 ]


Verwijderd

Verwijderd schreef op 26 November 2002 @ 15:19:
[...]

FOUT! Een impliciet gegenereerde copy ctor is niks anders dan een 1-op-1 mem-copy!
O ja?
Paragraaf 12.8.8 uit de ISO C++ standaard:

The implicitly defined copy constructor for class X performs a memberwise copy of its subobjects. The order of copying is the same as the order of initialization of bases and members in a userdefined constructor (see 12.6.2). Each subobject is copied in the manner appropriate to its type:
— if the subobject is of class type, the copy constructor for the class is used;
— if the subobject is an array, each element is copied, in the manner appropriate to the element type;
— if the subobject is of scalar type, the builtin assignment operator is used.

Virtual base class subobjects shall be copied only once by the implicitlydefined
copy constructor (see 12.6.2).
Als jij aan gcc ontwikkelt, moet dit toch geen nieuws voor je zijn.

Verwijderd

Verwijderd schreef op 26 november 2002 @ 15:02:
Dan moet je ook weten dat een C++ compiler default constructors en default assignment-operators mag wegoptimaliseren. Op het moment dat je deze default-members overschrijft met eigen versies kan/mag de compiler deze optimalisaties niet meer doen. Reden te meer om ze niet te overschrijven als het niet nodig is.
Mag ja, maar dat is niet aan te raden. Algemeen genomen heb je bijna niets veel aan deze "optimalisatie" (memcpy 1-op-1 is maar een heel klein beetje sneller) en krijg je slechtere code/gewoonte van terug.
edit:
Bitwise copy is uit, memberwise copy is defacto standaard, loop achter en idd copy-ctor/assignment operator alleen nodig voor de exotische classes zelf. Krijg je als je al tijden meerder verschillende compilers moet gebruiken, dan hou je moeilijker bij waneer ze allemaal conform bepaalde regels zijn geworden.

[ Voor 45% gewijzigd door Verwijderd op 28-11-2002 10:02 ]


Verwijderd

edit:
Toen ik begon met C++ deed minstens een compiler dit niet (maar volgens mij het merendeel?! Zou mijn docent destijds eens moeten uithoren)

Maar je verliest er kwa code-size niets mee en de kans dat je een copy ctor voor een exotische class vergeet te schrijven is kleiner. (class met pointers, usagecount, unieke id's, gekoppelde lijsten e.d.) Maar dat is idd (met de tegenwoordigcompilers) nog mijn enige argument voor.

[ Voor 79% gewijzigd door Verwijderd op 28-11-2002 10:09 ]


Verwijderd

O en voor debuggen is het ook een stuk handiger... En debuggen moet je wel in grote projecten.

[ Voor 186% gewijzigd door Verwijderd op 28-11-2002 09:50 . Reden: U mag deze verwijderen, o grote DRM!! ]


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

DaZaffiro: Die edit-knop zit er niet voor niets :) Afbeeldingslocatie: http://images.tweakers.net/forum/templates/got/images/icons/edit.gif

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Verwijderd schreef op 26 November 2002 @ 15:44:
[...]


De MSVC++ en de intel compiler doen dat in elk geval niet, de freeware BCC volgens mij ook niet, die doen een bitwise-copy, heb Gcc eigenlijk niet gechecked :o (ja stom |:( help met STL)
Zowel MSVC++.NET, Borland C++ Builder 6 en gcc 3.2 doen dit (dat zijn de compilers die ik hier bij de hand heb). Zou ook een beetje een zooitje worden als dit niet zo was. Voor een gcc ontwikkelaar moet dit toch gesneden koek zijn (ook als je alleen aan de stdlib werkt).

Verwijderd

Oke, maar dat is dan ook wel de nieuwste meuk...
edit:
Hmm, werkt ook goed met wat minder nieuw. Wat is het dan al weer lang geleden dat ik les kreeg in "gestructureerd C++" en je met dit soort problemen rekening moest houden. (Hoef idd niet iemand te leren rekening te houden met verouderde compilers als die niet meer gebruikt worden).

Maar je houdt het probleem met pointers/dynamische geheugen allocaties!!! Geen performanceverlies als je het zelf doet, wel een stuk duidelijker en betere QA van je code, dus zie geen reden om het weg te laten (zeker niet als je een paar simpele editor-macro's kunt schrijven).
edit:
Tegenwoordig hoef je idd alleen nog maar de copy ctor van exotische classes te schrijven en niet meer van alle classes die exotische classen gebruiken of die die classes weer gebruiken. Voor documentatie ook niet meer nodig, aangezien het (allang) standaard c++ is om copy ctor van memberclasses te gebuiken...

[ Voor 54% gewijzigd door Verwijderd op 28-11-2002 09:49 . Reden: liep achter... ]


Verwijderd

Verwijderd schreef op 26 november 2002 @ 15:02:
Dan moet je ook weten dat een C++ compiler default constructors en default assignment-operators mag wegoptimaliseren. Op het moment dat je deze default-members overschrijft met eigen versies kan/mag de compiler deze optimalisaties niet meer doen.
Ik neem aan dat je het wegoptimaliseren van temporaries bedoeld? In dat geval is dit geen argument, omdat voor dat soort optimalisaties geen onderscheid wordt gemaakt tussen default en non-default copy constructors:
ISO-IEC 14882-1998, 12.8 para 15:
Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the same cv-unqualified type, an implementation is permitted to treat the original and the copy as two different ways of referring to the same object and not perform a copy at all, even if the class copy constructor or destructor have side effects. (idem voor functies met class return types die local objects returnen)

Verwijderd

Verwijderd schreef op 26 November 2002 @ 16:20:
En je houdt het probleem met pointers/dynamische geheugen allocaties!!!
Niet als je die netjes wrapt in classes die wel normale value-semantics hebben. 'Rauwe' pointers gebruik ik alleen voor reassignable verwijzingen naar objecten die ik niet beheer, en pointers die zo gebruikt worden kunnen zonder probleem simpel gekopieerd worden.
Geen performanceverlies als je het zelf doet, wel een stuk duidelijker en betere QA van je code, dus zie geen reden om het weg te laten (zeker niet als je een paar simpele macro's kunt schrijven).
Hmm, je ziet het kunnen weglaten van compleet overbodige code en daarnaast het kunnen vermijden van inelegante macro's niet als een reden om voor elegantere default copy constructors en copy assignment operators te kiezen? Apart..

Verwijderd

Verwijderd schreef op 26 november 2002 @ 16:49:
Hmm, je ziet het kunnen weglaten van compleet overbodige code niet als een reden om voor elegantere default copy constructors en copy assignment operators te kiezen? Apart..
I vind het persoonlijk eleganter dat ik m'n constructors zelf schrijft, vind ik handiger te debuggen, zie ik sneller dat ik zo stom was een assignment te vergeten (en dat vloert dus al m'n vorige argumenten omdat ik gewoonweg niet weet dat compilers tegenwoordig memberwise kopieren)
en daarnaast het kunnen vermijden van inelegante macro's
Ging om editor macro's, had idd duidelijker moeten zijn sh*t ik heb m'n dag niet zo.
Idd GCC-3.2 doet wel memberwise, loop achter op C++ specificatie.

offtopic:
DaZaffiro overreacted. |:( |:( |:( |:( |:(
En het is niet elegant nee, mijn excuses aan allen!!!
Heb dit bericht dan ook maar eens vlug veranderd in wat het eigenlijk maximaal had mogen zijn.

[ Voor 93% gewijzigd door Verwijderd op 28-11-2002 10:58 ]


Verwijderd

Verwijderd schreef op 26 November 2002 @ 17:11:
Het is eleganter als je je constructors zelf schrijft ja, eleganter want dan is het tenminste in de code te lezen wat er gebeurt, en is dit tenminste goed te debuggen ja
Wat maakt een hersenloze expliciet-getypte memberwise copy volgens jouw zo waardevol voor het debuggen?
Ging dus om editor macro's. Die vermijden :? Dan doe je pas een hoop overbodig werk...
Ik ging uiteraard uit van C/C++ macro's :X.
.modbreak: stuk weggehaald, wat hier stond doet er verder niet toe
Met die instelling is jouw aanwezigheid op GoT voor zowel jouwzelf als de rest hier inderdaad wellicht zinloos. Ook ik zit me hier af te vragen hoe we jouw nu enig gevoel voor stijl en elegantie bij kunnen brengen, maar als jij overgaat tot kansloze flames hoeft het van mij niet meer.

[ Voor 15% gewijzigd door .oisyn op 26-11-2002 23:07 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:03

.oisyn

Moderator Devschuur®

Demotivational Speaker

DaZaffiro: jouw arrogantie staat mij niet bepaald aan, deze gaat dan ook op slot voordat het losbarst in een flamewar

.edit: open op verzoek, DaZaffiro heeft beloofd zijn statement in te trekken, ik wil iedereen verzoeken daar verder niet meer op in te gaan

[ Voor 37% gewijzigd door .oisyn op 26-11-2002 19:25 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Verwijderd schreef op 26 November 2002 @ 16:37:
Ik neem aan dat je het wegoptimaliseren van temporaries bedoeld? In dat geval is dit geen argument, omdat voor dat soort optimalisaties geen onderscheid wordt gemaakt tussen default en non-default copy constructors:
Klopt, ik had geen standaard bij de hand maar meende het me zo te herinneren. Ik was in de war met trivial vs. non-trivial constructors, maar dat heeft niks te doen met copy constructors. Mja, al de tweede post dat ik echt lulkoek vertel in drie dagen. Ik denk dat ik me voorlopig maar es lekker op de programming contest ga richten :z

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 26 november 2002 @ 13:36:
[...]

Oneens. Zodra je dynamisch alloceerbaar geheugen gebruikt, gaat het al snel fout. Dan moet je namelijk het oorspronkelijk gealloceerde geheugen verwijderen, sja, dat gaat fout...
Je moet als je met dynamisch geheugen werkt maatregelen nemen om exception-safe te zijn. Dat betekent dat je nieuw geheugen alloceert voordat je het oude weggooit. En dat betekent weer, dat je ook bij self-assignment veilig bent.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 26 november 2002 @ 15:38:
En toen kwam d'r een stagiar en die moest er een member aan toe voegen en laat dat nu net een pointer geweest zijn...
Het beging misschien bekend te klinken, maar vanwege exception-safety mag je nooit owning raw pointers toevoegen als class members. De geownde resource wordt niet vrijgegeven als de class ctor faalt. Was het bv. een auto_ptr<> geweest, dan was die resource wel vrijgegeven.

PS. DaZaffiro , wat doe je precies aan GCC?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSalters schreef op 27 november 2002 @ 12:24:
Het beging misschien bekend te klinken, maar vanwege exception-safety mag je nooit owning raw pointers toevoegen als class members. De geownde resource wordt niet vrijgegeven als de class ctor faalt. Was het bv. een auto_ptr<> geweest, dan was die resource wel vrijgegeven.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
MyClass::MyClass()
{
try
  {
  A = NULL;
  B = NULL;
  A = new Pietje;
  B = new Klaasje;
  ...
  }
catch(...)
  {
  delete A;
  delete B;
  throw;
  }
}

Ut kan wel, maar niet al te charmant :) Maja ik doe ook alles met smart pointers om dit soort redenen.

Professionele website nodig?


Verwijderd

FF ter uitleg: de tid dat ik moest leren programmeren in C++ deed in elk geval één compiler een bitwise-copy als je de copy ctor wegliet, en moest je d'r dus voor zorgen dat elke class die een "uitzonderings" class gebruikte, ook een uitgeschreven copy-ctor bevatte.
Dat is dus al lang geleden :D en vroeg me al af waarom men tegenwoordig niet meer geleerd wordt om een copy ctor te maken... :X Daarom wou ik degene die hier om wat tips vroeg d'r even op attenderen, maar ik loop dus achter, idd elke compiler kleit een copy ctor in elkaar die de copy-ctor van memberclasses aanroept enzovoort, en hoeft er alleen bij de "uitzonderings" class de ctor zelf gecodeerd te worden en het gaat goed... |:( (Uitzonderingsclass is bijvoorbeeld een class met een uniek id (m.b.v. een static datamember) en/of een next/previous pointer e.d. Dirty tricks die wel de benodigde performance een stuk omhoog gooien. )

Maar nu een vraagje: geldt dit dan ook automatisch voor assignment operator (dus dat assignment-operators van memberclasses wordt gebruikt) en misschien zelfs ook voor ander operators? (Zal niet zo vaak voorkomen/handig zijn, maar voor de zekerheid) Dus voor alle huidig, gebruikelijke compilers?

Verwijderd

MSalters schreef op 27 november 2002 @ 12:17:
Je moet als je met dynamisch geheugen werkt maatregelen nemen om exception-safe te zijn. Dat betekent dat je nieuw geheugen alloceert voordat je het oude weggooit. En dat betekent weer, dat je ook bij self-assignment veilig bent.
Idd in exeptionsafe maakt het geen feitelijk verschil, maar als het gaat om ruwe performance kan het in situaties wel echt lonen om te checken of je het niet al zelf bent: kost hooguit een compare en een conditionele jump, scheelt tijd en de geheugen in de vorm van de temp. buffer die je anders nodig hebt. Zal op de desktop ook vast idd niet zo uitmaken, dat beetje extra gealloceerde geheugen.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 28 November 2002 @ 09:38:
Maar nu een vraagje: geldt dit dan ook automatisch voor assignment operator (dus dat assignment-operators van memberclasses wordt gebruikt) en misschien zelfs ook voor ander operators? (Zal niet zo vaak voorkomen/handig zijn, maar voor de zekerheid) Dus voor alle huidig, gebruikelijke compilers?
Assignment wèl, rest niet. Reden: compabiliteit met C ( die genereert ook copy&assignment).
12 Special member functions [special]
The default constructor (12.1), copy constructor and copy assignment operator (12.8), and destructor (12.4) are special member functions. The implementation will implicitly declare these member functions for a class type when the program does not explicitly declare them, except as noted in 12.1. The implementation will implicitly define them if they are used, as specified in 12.1, 12.4 and 12.8.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Verwijderd schreef op 28 november 2002 @ 10:42:
[...]

Idd in exeptionsafe maakt het geen feitelijk verschil, maar als het gaat om ruwe performance kan het in situaties wel echt lonen om te checken of je het niet al zelf bent: kost hooguit een compare en een conditionele jump, scheelt tijd en de geheugen in de vorm van de temp. buffer die je anders nodig hebt. Zal op de desktop ook vast idd niet zo uitmaken, dat beetje extra gealloceerde geheugen.
Ja, alleen is in de praktijk self-assignment zo zeldzaam dat het voordelig is om die check te verwijderen. Die check kost in 99, 9x% van de assignments een beetje tijd, dan moet de winst in de orde-grootte van enkele duizenden jumps liggen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

"...Kan het lonen" staat d'r dan ook, maar dan moet -als je het om de snelheid doet- idd gelden dat:
(clockcylces assignmentalgorithme) >= (clockcycles compare + jump) / (kans selfassignment)

Dus voor een x86-systeem zou in jouw voorbeeld moeten gelden dat:
assignmentalgorithme >= 2 cycles / (1/1000) = 2000 cycles. Dat is wel rendabel voor een hoognivo assigment (die kost al snel meer dan 2000 cycles). Ook zijn er systemen waarbij het alloceren van geheugen (voor een buffer) pas echt veel tijd kan gaan kosten of moeilijk kan passen, en je dus moet proberen dit te voorkomen...

Een kans van 0.1% is echter nog behoorlijk hoog, slechts in bepaalde gevallen zal dit 1% of meer zijn, in veel gevallen is die kans al uitgesloten door het ontwerp. (Een relateerbaar voorbeeld uit de lucht waar de kans statistisch groter dan 1% is, en de tijd voor een assignment behoorlijk lang: de syntaxhighlighting parser van een editor op een ander language instellen, nadat de bestandsnaam is veranderd)
Ik ga ook alleen maar na bij de classes met de hoogste abstractie of het loont, dus ook alleen voor die uitzonderingen en die classes waar uberhaupt een (exotische) assignment definitie voor nodig is (daar is volgens mij de kans ook het grootst op selfassignment). Voor de desktop zou ik het ook verder ook niemand aanraden denk ik, lijkt mij meer tijdverspilling dan winst (met de huidige proc. snelheden: who cares?)).
Pagina: 1