[C++] constructor-overloading+inheritance en kleine vraagjes

Pagina: 1
Acties:

  • JeromeB
  • Registratie: September 2003
  • Laatst online: 19-03 22:07
Geachte dames en heren, welkom in mijn topic. :)

Ik ben sinds een weekje bezig om wat praktijk-ervaring optedoen met betrekking tot C++ en OOP.
Ik heb een aantal vragen. Ik hoop dat jullie ze kunnen en willen beantwoorden.

Ik gebruik trouwens de Mingw32-compiler icm Dev-C++ 4.


de this pointer binnen classes:

In de meeste gevallen mag binnen een class de "this pointer" weggelaten worden.
Wat is hier de reden voor?
In welke gevallen is het niet toegestaan?
Wat vinden jullie hier zelf van?


constructor-overloading + inheritance:

In voorbeeld 1 erft de Derived-class automatisch de constructor van de Base-class. Bij het instantieren van de Derived-class wordt dus autoamatisch het getal 10 toegekent aan de variabele test.
In voorbeeld 2 wil ik die constructor overloaden in de Derived-class. Dat werkt echter niet. Ik krijg een error: "no matching function for call to 'Derived::Derived()' candidates are bla bla".
Ik heb toen het volgende toegevoegt aan de Derived-class:
code:
1
Derived();
. Dat werkt echter niet en ik krijg een link-error: "undefined reference to 'Derived::Derived(void)'".
Als ik
code:
1
Derived(){}
toevoeg dan werkt het wel.

Waarom werkt voorbeeld 2 niet en waarom geeft voorbeeld 3 een link-error?

voorbeeld 1:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Base {
    public:
        Base() {
            test = 10;
        }
    protected:
        int test;
};

class Derived : public Base {
    public:
        int getTest() {
            return test;
        }
};

int main() {
    Derived bloeb;
    std::cout << bloeb.getTest() << std::endl; // geeft 10 weer
    return 0;
}

voorbeeld 2:
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
class Base {
    public:
        Base() {
            test = 10;
        }
    protected:
        int test;
};

class Derived : public Base {
    public:
        Derived(int i) {
            test = i;
        }

        int getTest() {
            return test;
        }
};

int main(){
    Derived bloeb; // no matching function for call to 'Derived::Derived()'
    std::cout << bloeb.getTest() << std::endl;
    return 0;
}

voorbeeld 3:
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
class Base {
    public:
        Base() {
            test = 10;
        }
    protected:
        int test;
};

class Derived : public Base {
    public:
        Derived(){} // Als ik deze regel toevoeg werkt het wel

        Derived(int i) {
            test = i;
        }

        int getTest() {
            return test;
        }
};

int main() {
    Derived bloeb; // werkt
    std::cout << bloeb.getTest() << std::endl; // geeft 10 weer.
    return 0;
}



swap functie:

Na een kleine zoektocht kwam ik terecht bij het begrip "pass-by-reference". Ik kreeg daarbij 2 voorbeelden voorgeschoteld. Men zij dat voorbeeld 1 netter is, omdat voorbeeld 2 problemen kon veroorzaken. Er werd echter niet uigelegd wat die problemen zijn. Kunnen jullie mij dat uitleggen?

voorbeeld 1:
C++:
1
2
3
4
5
void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}


voorbeeld 2:
C++:
1
2
3
4
5
void swap(int &a, int &b) {
    a = a+b;
    b = a-b;
    a = a-b;
}



pointers:
Ik gebruik structs als containers voor punten. Deze punten gebruik ik weer in andere classes om mee te rekenen. Er zijn 3 mogelijkheden die werken. Ikzelf gebruik pointers (voorbeeld 1), maar ik vraag mij af wat daar het voordeel van is. Ik heb niet zoveel ervaring met het gebruik van pointers. Wat geniet jullie voorkeur en waarom?
offtopic:
Ik begrijp dat ik in mijn voorbeelden de constructor een beetje misbruik.

voorbeeld 1 (pointers):
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
struct Point2D {
    float x;
    float y;
};

class qbc {
    public:
        qbc(Point2D *a, Point2D *b) {
            std::cout << "x: " << this->midpoint(a,b).x << std::endl;
            std::cout << "y: " << this->midpoint(a,b).y << std::endl;
        }

        Point2D midpoint(Point2D *a, Point2D *b) {
            Point2D point;
            point.x = (a->x+b->x)/2;
            point.y = (a->y+b->y)/2;
            return point;
        }

};

int main() {
    Point2D punt1 = {20,20};
    Point2D punt2 = {300,200};
    qbc bloeb(&punt1,&punt2);
    system("PAUSE");
    return 0;
}

voorbeeld 2 (lokale variabeles):
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
struct Point2D {
    float x;
    float y;
};

class qbc {
    public:
        qbc(Point2D a, Point2D b) {
            std::cout << "x: " << this->midpoint(a,b).x << std::endl;
            std::cout << "y: " << this->midpoint(a,b).y << std::endl;
        }

        Point2D midpoint(Point2D a, Point2D b) {
            Point2D point;
            point.x = (a.x+b.x)/2;
            point.y = (a.y+b.y)/2;
            return point;
        }

};

int main() {
    Point2D punt1 = {20,20};
    Point2D punt2 = {300,200};
    qbc bloeb(punt1,punt2);
    system("PAUSE");
    return 0;
}

voorbeeld 3 (references):
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
struct Point2D {
    float x;
    float y;
};

class qbc {
    public:
        qbc(Point2D &a, Point2D &b) {
            std::cout << "x: " << this->midpoint(a,b).x << std::endl;
            std::cout << "y: " << this->midpoint(a,b).y << std::endl;
        }

        Point2D midpoint(Point2D &a, Point2D &b) {
            Point2D point;
            point.x = (a.x+b.x)/2;
            point.y = (a.y+b.y)/2;
            return point;
        }

};

int main() {
    Point2D punt1 = {20,20};
    Point2D punt2 = {300,200};
    qbc bloeb(punt1,punt2);
    system("PAUSE");
    return 0;
}

PC load letter? What the fuck does that mean?


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

JeromeB schreef op zaterdag 09 april 2005 @ 19:48:
de this pointer binnen classes:

In de meeste gevallen mag binnen een class de "this pointer" weggelaten worden.
Wat is hier de reden voor?
In welke gevallen is het niet toegestaan?
Wanneer je een parameter hebt met dezelfde naam:
C++:
1
2
3
void MyClass::MyFunc(int blaat) {
  this->blaat = blaat;
}
Wat vinden jullie hier zelf van?
Wat maakt het uit? Het is gewoon zo. :P
constructor-overloading + inheritance:

In voorbeeld 1 erft de Derived-class automatisch de constructor van de Base-class. Bij het instantieren van de Derived-class wordt dus autoamatisch het getal 10 toegekent aan de variabele test.
In voorbeeld 2 wil ik die constructor overloaden in de Derived-class. Dat werkt echter niet. Ik krijg een error: "no matching function for call to 'Derived::Derived()' candidates are bla bla".
Ik heb toen het volgende toegevoegt aan de Derived-class:
code:
1
Derived();
. Dat werkt echter niet en ik krijg een link-error: "undefined reference to 'Derived::Derived(void)'".
Als ik
code:
1
Derived(){}
toevoeg dan werkt het wel.

Waarom werkt voorbeeld 2 niet en waarom geeft voorbeeld 3 een link-error?
Je moet voor je class natuurlijk wel die standaard constructor meenemen (geloof ik, mijn C++ kennis is wat stoffig):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
class Derived : public Base {
    public:
        Derived():Base() {}  // <-----

        Derived(int i) {
            test = i;
        }

        int getTest() {
            return test;
        }
};
swap functie:

Na een kleine zoektocht kwam ik terecht bij het begrip "pass-by-reference". Ik kreeg daarbij 2 voorbeelden voorgeschoteld. Men zij dat voorbeeld 1 netter is, omdat voorbeeld 2 problemen kon veroorzaken. Er werd echter niet uigelegd wat die problemen zijn. Kunnen jullie mij dat uitleggen?
De voorbeelden die je laat zien zijn gewoon verschillende manieren om twee variabelen te swappen, wat verder niet per se wat met passing by reference te maken heeft. Daarbij maakt het echt uit welke van de twee methoden je gebruiken, aangezien ze beiden zouden moeten werken, maar de eerste is meer gangbaar omdat het veel makkelijker te lezen en begrijpen is.
pointers:
Ik gebruik structs als containers voor punten. Deze punten gebruik ik weer in andere classes om mee te rekenen. Er zijn 3 mogelijkheden die werken. Ikzelf gebruik pointers (voorbeeld 1), maar ik vraag mij af wat daar het voordeel van is. Ik heb niet zoveel ervaring met het gebruik van pointers. Wat geniet jullie voorkeur en waarom?
offtopic:
Ik begrijp dat ik in mijn voorbeelden de constructor een beetje misbruik.
Volgens mij snap je niet helemaal wat een pointer is. Pointers worden voor duizenden dingen gebruikt, omdat wat een pointer is, feitelijk niet meer is dan een verwijzing naar een geheugenadres waar datgene staat dat je wil aanspreken. Arrays zijn pointers. Strings zijn pointers. Geef je een array of string mee aan een functie, dan gebeurt dat via pointers (al is dat in C++ veel minder duidelijk dan in C). Je moet gewoon per situatie kiezen wat het handigst is in gebruik. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • JeromeB
  • Registratie: September 2003
  • Laatst online: 19-03 22:07
-NMe- schreef op zaterdag 09 april 2005 @ 19:59:
[...]

Wanneer je een parameter hebt met dezelfde naam:
C++:
1
2
3
void MyClass::MyFunc(int blaat) {
  this->blaat = blaat;
}
ok, bedankt, dat begrijp ik.
-NMe- schreef op zaterdag 09 april 2005 @ 19:59:
[...]

Wat maakt het uit? Het is gewoon zo. :P
Ik doelde eigenlijk op het weglaten van de this pointer wanneer de die niet per sé nodig is.
Maar je hebt gelijkt. Ieder mens heeft zijn/haar eigen voorkeuren en dus maakt het niet uit.
-NMe- schreef op zaterdag 09 april 2005 @ 19:59:
[...]

Je moet voor je class natuurlijk wel die standaard constructor meenemen (geloof ik, mijn C++ kennis is wat stoffig):
C++:
1
2
3
4
5
6
7
8
9
10
11
12
class Derived : public Base {
    public:
        Derived():Base() {}  // <-----

        Derived(int i) {
            test = i;
        }

        int getTest() {
            return test;
        }
};
Dat klinkt logisch, maar waarom hoef ik dat in voorbeeld 1 niet te doen?
-NMe- schreef op zaterdag 09 april 2005 @ 19:59:
[...]

De voorbeelden die je laat zien zijn gewoon verschillende manieren om twee variabelen te swappen, wat verder niet per se wat met passing by reference te maken heeft. Daarbij maakt het echt uit welke van de twee methoden je gebruiken, aangezien ze beiden zouden moeten werken, maar de eerste is meer gangbaar omdat het veel makkelijker te lezen en begrijpen is.
Ik begrijp wel wat pass-by-reference is. Ik wilde eigenlijk alleen aangeven dat ik bij mijn zoektocht naar "pass-by-reference" die 2 swap functies tegenkwam.
-NMe- schreef op zaterdag 09 april 2005 @ 19:59:
[...]

Volgens mij snap je niet helemaal wat een pointer is. Pointers worden voor duizenden dingen gebruikt, omdat wat een pointer is, feitelijk niet meer is dan een verwijzing naar een geheugenadres waar datgene staat dat je wil aanspreken. Arrays zijn pointers. Strings zijn pointers. Geef je een array of string mee aan een functie, dan gebeurt dat via pointers (al is dat in C++ veel minder duidelijk dan in C). Je moet gewoon per situatie kiezen wat het handigst is in gebruik. :)
Ik begrijp wel ongeveer wat pointers zijn. Ik begrijp alleen niet goed in welke gevallen pointers handig kunnen zijn (dat geld trouwens ook voor references). En in dit geval zou ik het echt niet weten.

Waarschijnlijk heb ik gewoon meer ervaring nodig.

Bedankt :)

PC load letter? What the fuck does that mean?


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
JeromeB schreef op zaterdag 09 april 2005 @ 19:48:
In de meeste gevallen mag binnen een class de "this pointer" weggelaten worden.
Wat is hier de reden voor?
In welke gevallen is het niet toegestaan?
Wat vinden jullie hier zelf van?
De voornaamste bedoeling van de this-pointer is niet om er members mee aan te duiden, maar om functies een pointer naar het huidige object mee te kunnen. Dit wordt vaak gebruikt om later callbacks te kunnen doen. Object A registreert zichzelf als een event-listener (door de this-pointer als argument mee te geven aan de registratie-functie), zodat als er een event gebeurt, de event-handle functies aangeroepen kunnen worden van de geregistreerde objecten.
In voorbeeld 1 erft de Derived-class automatisch de constructor van de Base-class. Bij het instantieren van de Derived-class wordt dus autoamatisch het getal 10 toegekent aan de variabele test.
Niet helemaal. Volgens mij worden constructors niet overgeerfd. Wat er gebeurt is omdat er in voorbeeld 1 geen constructor gedefinieerd is, en er een default-constructor gegenereerd wordt.
In voorbeeld 2 wil ik die constructor overloaden in de Derived-class. Dat werkt echter niet. Ik krijg een error: "no matching function for call to 'Derived::Derived()' candidates are bla bla".
Hier heb je wel een constructor gedefinieerd (met 1 argument), zodat er geen default constructor voor je gegenereerd wordt. Omdat constructors niet geerfd worden, is er dus geen goede candidaat beschikbaar. Oplossing: declareer in je derived class expliciet een default constructor, of initialiseer alle Derived-instanties *met* parameter (dus: Derived bloeb(5);)
Ik heb toen het volgende toegevoegt aan de Derived-class:
code:
1
Derived();
. Dat werkt echter niet en ik krijg een link-error: "undefined reference to 'Derived::Derived(void)'".
Klopt, de compiler slikt het dan wel, omdat je dmv deze regel de compiler belooft dat er een constructor met deze signature bestaat. Je declareert (=belooft) deze constructor wel, maar je implementeert 'm niet (je sluit het statement af met een puntkomma, niet met een implementatie {...}).
Als ik
code:
1
Derived(){}
toevoeg dan werkt het wel.
Klopt, de {} stelt de implementatie voor, (het 'doet' alleen niks). Maar dan is je constructor wel geimplementeerd, en dus klaagt de linker niet meer.

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
Na een kleine zoektocht kwam ik terecht bij het begrip "pass-by-reference". Ik kreeg daarbij 2 voorbeelden voorgeschoteld. Men zij dat voorbeeld 1 netter is, omdat voorbeeld 2 problemen kon veroorzaken. Er werd echter niet uigelegd wat die problemen zijn. Kunnen jullie mij dat uitleggen?
Mogelijke problemen voor ints zijn overflows (dwz het resultaat is te groot voor een int). Ik vermoed bijv. dat het swappen van ints met waarden 0x50000000 en 0x60000000 fout gaat, omdat het resultaat 0xB0000000 niet kan in een signed int (de hoogste bit is voor het teken van het getal).
Los daarvan ben je aangewezen op de beschikbaarheid van + en - operatoren. Voor ints is dit geen probleem, maar hoe zou je twee MyClass instanties swappen? Dit kan prima op de 1e manier, maar niet op de tweede manier.
Ik gebruik structs als containers voor punten. Deze punten gebruik ik weer in andere classes om mee te rekenen. Er zijn 3 mogelijkheden die werken. Ikzelf gebruik pointers (voorbeeld 1), maar ik vraag mij af wat daar het voordeel van is. Ik heb niet zoveel ervaring met het gebruik van pointers. Wat geniet jullie voorkeur en waarom?
References. Je kan je zelfs const maken:
C++:
1
qbc(const Point2D &a, const Point2D &b) {

Optie 1 (pointers) is niet wenselijk omdat er NULL pointers meegegeven kunnen worden, die ervoor zorgen dat je methode niet werkt. Optie 2 is niet handig omdat het een compleet nieuwe kopie maakt van je parameters. Voor een point van 2 ints is dit niet zo erg, maar je kan je voorstellen dat als je bitmaps op deze manier door gaat geven, dat het flink wat geheugen gaat kosten.
Optie 3 is het beste, omdat er geen apart kopie wordt gemaakt van je parameters, terwijl je wel met ze kan werken alsof ze by value zijn gepassed. Door 'const' references te gebruiken, beloof je dat de functie deze objecten niet zal veranderen (wat in veel gevallen wenselijk is).

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
JeromeB schreef op zaterdag 09 april 2005 @ 19:48:


constructor-overloading + inheritance:

In voorbeeld 1 erft de Derived-class automatisch de constructor van de Base-class. Bij het instantieren van de Derived-class wordt dus autoamatisch het getal 10 toegekent aan de variabele test.
Eh, nee. Het werkt iets anders. Elke Derived constructor roept Base::Base( ) aan, tenzij je expliciet aangeeft dat je een andere Base ctor wil. Dat doe je door : Base ( argument ) tussen de ) en de { te zetten
In voorbeeld 2 wil ik die constructor overloaden in de Derived-class. Dat werkt echter niet. Ik krijg een error: "no matching function for call to 'Derived::Derived()' candidates are bla bla".
Ik heb toen het volgende toegevoegt aan de Derived-class:
code:
1
Derived();
. Dat werkt echter niet en ik krijg een link-error: "undefined reference to 'Derived::Derived(void)'".
Als ik
code:
1
Derived(){}
toevoeg dan werkt het wel.

Waarom werkt voorbeeld 2 niet en waarom geeft voorbeeld 3 een link-error?
Kijk, als je begrijpt dat je Base::base niet inherit, dan zie je misschien al wat er fout gaat. In voorbeeld 2 declareer je een Derived::Derived(int). Dat voorkomt dat de compiler een default ctor voor Derived declareert of definieert. Vervolgens voeg je alleen een declaratie toe. Dan is de compiler tevreden, maar je moet wel ergens anders een definitie voor Derived::Derived zetten. Je gebruikt die ctor namelijk wel. Als je echter die ctor definieert, als is het maar als een lege { } ctor, dan is de compiler tevreden. Alle base classes en members worden dan default geinitialiseerd (let op: dat doet dus niets voor types zonder ctor, zoals pointers of int)

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


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 02-05 01:32
Een heleboel vragen, ik zal even een poging doen de vragen die anderen nog niet behandelt hebben voor mijn rekening te nemen.
JeromeB schreef op zaterdag 09 april 2005 @ 19:48:
Men zij dat voorbeeld 1 netter is, omdat voorbeeld 2 problemen kon veroorzaken. Er werd echter niet uigelegd wat die problemen zijn. Kunnen jullie mij dat uitleggen?

voorbeeld 1:
C++:
1
2
3
4
5
void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}


voorbeeld 2:
C++:
1
2
3
4
5
void swap(int &a, int &b) {
    a = a+b;
    b = a-b;
    a = a-b;
}
MrBucket gaf al aan dat de eerste beter is omdat hij veel algemener is. Er bestaat ook een swap-functie in de standard library, die ongeveer (of misschien wel precies) zo werkt:
C++:
1
2
3
4
5
template class T void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
};

Dit werkt voor elke T waarvoor een copy constructor en assignment-operator gedefinieerd is. (Normaal gesproken alle klassen, al kun je het ook stuk maken.) Het tweede voorbeeld werkt dus alleen met ints en gaat waarschijnlijk wel goed (ook bij overflows), maar het zou kunnen dat het gedrag bij overflows niet gespecificeerd is (dat weet MSalters vast wel te vertellen. ;)).

pointers:
Ik gebruik structs als containers voor punten. Deze punten gebruik ik weer in andere classes om mee te rekenen. Er zijn 3 mogelijkheden die werken. Ikzelf gebruik pointers (voorbeeld 1), maar ik vraag mij af wat daar het voordeel van is. Ik heb niet zoveel ervaring met het gebruik van pointers. Wat geniet jullie voorkeur en waarom?
In jouw voorbeeld doe je het naar mijn mening goed fout. Het voordeel van een pointer in C++ is dat 'ie null kan zijn, wat met een reference niet kan. Als je een functie hebt die op twee argumenten werkt en je wil altijd gewoon twee argumenten hebben (zoals in jouw midpoint-voorbeelden) dan is een reference de juiste keuze. Als iemand er een null-pointer in stopt kan het alleen maar misgaan en door een reference-type te gebruiken geef je gewoon aan dat dat niet kan. Pointers worden vaak op lager nivo gebruikt (bijvoorbeeld om een datastructuren te maken zoals linked lists of binary trees) of dus als een argument optioneel is.

Verder dien je argumenten die je niet wijzigt by const reference te declareren. Dan geef je ook aan aan de aanroeper dat je het argument niet zult wijzigen (en dan hoeft de aanroeper ook geen kopie te maken als 'ie zelf al een const object had).

Tenslotte worden vaak pointers gebruikt als je het 'eigendom' van een op de heap gealloceerd object overdraagt. Dat is meer een conventie, maar het is logisch omdat new en delete zelf ook pointers gebruiken.

De regels zijn dus:
• Pointer als een argument optioneel is/null kan zijn, of als je eigendom van geheugen overdraagt
• Const-reference als je een argumenten gebruikt maar niet wijzigt (bijvoorbeeld: Point2D midpoint(const Point2D &a, const Point2D &b))
• Gewone reference als je argumenten gebruikt en wijzigt (bijvoorbeeld: void swap(T &a, T &b)).
Eigenlijk wordt er ontzettend weinig van deze regel afgeweken (of ik ben wat vergeten).

Verder wordt voor typische value types ook wel pass-by-value gebruikt. (Helemaal geen reference dus.) Doe dat alleen als je zeker weet dat het maken van een kopie goedkoop is, of als je per se een kopie wil hebben (al kan ik me daar geen reden bij voorstellen). Bijvoorbeeld basic types als ints en chars worden altijd gewoon by-value doorgegeven meestal. Eventueel zou je het bij simpele, kleine, value-achtige structuurs ook kunnen doen (bijvoorbeeld 32-bits union/struct waar een IP-adres in zit ofzo), maar dat is meer een kwestie van smaak en micro-optimalisatie.

  • JeromeB
  • Registratie: September 2003
  • Laatst online: 19-03 22:07
Iedereen bedankt. Het is voor mij allemaal een stuk duidelijker. :)

Ik heb nog wel een vraag mbt references in containers.
Is het mogelijk om references in een container te plaatsen?

In voorbeeld 1 plaats ik een copy van 'punt' in de container. Dit is niet wenselijk. Als ik de waarde van 'punt' wijzig dan blijft de waarde in de container gewoon 20.

Het zou dus handig zijn als ik in de container een reference (naar 'punt') kon plaatsen. In voorbeeld 2 probeer ik dit te doen. Ik krijg echter de volgende error: "no matching functin for call to 'vector<Point,allocator<Point> >::push_back (Point *)' candidates are bla bla".

voorbeeld 1:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
struct Point {
    float x,y;
}

int main() {
    Point punt = {20,20};
    std::vector<Point> bloeb;
    bloeb.push_back(punt);
    punt.x = 100;
    std::cout << bloeb[0].x << std::endl; // geeft 20 weer
    return 0;
}

voorbeeld 2:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
struct Point {
    float x,y;
}

int main() {
    Point punt = {20,20};
    std::vector<Point> bloeb;
    bloeb.push_back(&punt); // error
    punt.x = 100;
    std::cout << bloeb[0].x << std::endl;
    return 0;
}

[ Voor 7% gewijzigd door JeromeB op 10-04-2005 13:56 . Reden: kleine type ]

PC load letter? What the fuck does that mean?


Verwijderd

Als je zoiets wilt doen moet je een vector met pointers maken. std::vector<Point*>.
Dan heb je hetzelfde. een vector van references gaat niet, std::vector::<Point&> = niet doen!.

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Op regel 8 van voorbeeld 2 geef je juist het adres van de variabele punt door, en dus een pointer. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • JeromeB
  • Registratie: September 2003
  • Laatst online: 19-03 22:07
Het werkt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Point {
    float x,y;
};

int main() {
    Point punt = {20,20};
    std::vector<Point*> bloeb;
    bloeb.push_back(&punt);
    punt.x = 100;
    std::cout << bloeb[0]->x << std::endl; // geeft 100 weer
    system("PAUSE");
    return 0;
}


Ik vind het allemaal nog wel verwarrend.
Dus inprincipe bewaar ik pointers in de container?
In dit geval is bloeb[0] een pointer naar punt?

PC load letter? What the fuck does that mean?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 07-05 10:04
JeromeB schreef op zondag 10 april 2005 @ 13:49:
Ik heb nog wel een vraag mbt references in containers.
Is het mogelijk om references in een container te plaatsen?
Nee. Net zomin het mogelijk is een ongeinitialiseerde reference te declaren.

Dus:
C++:
1
2
3
4
5
6
int main( int argc, char * argv[] )
{
    int& blaat;

    return 0;
}


Zal niet door de compiler komen. Als je dat weet dan kun je je voorstellen dat het niet mogelijk is om een container met een heleboel van de ongeinitialiseerde references te maken.

Je kunt echter wel een reference van een item in de container opvragen (meestal?), als het object er eenmaal inzit.

[ Voor 10% gewijzigd door farlane op 10-04-2005 14:38 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
farlane schreef op zondag 10 april 2005 @ 14:36:
Je kunt echter wel een reference van een item in de container opvragen (meestal?), als het object er eenmaal inzit.
Precies, en dit is dan ook wat TS eigenlijk zou moeten doen.

C++:
1
2
3
4
std::vector<Point> vPoints;
Point punt = {20,20};
vPoints.push_back(punt);  //vPoints[0] is nu (20, 20)
vPoints[0].x = 40;        //vPoints[0] is nu (40, 20)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 02-05 01:32
Sterker nog, op de stack gealloceerde objecten naar buiten brengen (door ze te retourneren of in een globale datastructuur te stoppen) is vragen om problemen. Hier geeft het niet, omdat de vector opgeruimd wordt voor het stackobject dat erin zit, maar in het algemeen wil je juist graag dat de vector een kopie maakt van de objecten die je er in stopt.

Verder verschilt het per container of je wel of niet objecten mag wijzigen. In een set zijn de elementen altijd geordend bijvoorbeeld en als je dan elementen op hun plaats wijzigt maak je 'm stuk.

[ Voor 5% gewijzigd door Soultaker op 10-04-2005 15:24 ]


  • JeromeB
  • Registratie: September 2003
  • Laatst online: 19-03 22:07
Nogmaals bedankt. In mijn programma is het inderdaad niet gewenst, ik was echter wel benieuwd naar de mogelijkheden.

PC load letter? What the fuck does that mean?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 07-05 10:04
JeromeB schreef op zondag 10 april 2005 @ 15:44:
Nogmaals bedankt. In mijn programma is het inderdaad niet gewenst, ik was echter wel benieuwd naar de mogelijkheden.
Als je wilt weten hoe je wel en niet met de STL containers kunt doen, er is een heleboel info op het web te vinden over dit onderwerp.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1