Toon posts:

[c++] temp data voor member initialisatie, hoe ?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Stel ik heb dit:
code:
1
2
3
4
5
6
7
8
9
10
struct Point { int x, y; };

void f (Point & p); // vult p's x en y in
struct A { A (int x, int y); };

struct B
{
  A a;
  B ();
};

Hoe kan ik dan zo makkelijk mogelijk in B::B() a initialiseren met de coordinaten van een f call ?

Ik zou natuurlijk een A* (auto)pointer ipv. een A kunnen gebruiken zodat ik in B::B()'s body een nieuw A object kan aanmaken en initialiseren met behulp van een local Point object waar ik f op los heb gelaten, maar deze methode bevalt me niet aangezien a dan een heap object is terwijl dat object precies dezelfde lifetime moet hebben als het B object..

Is deze pointer manier toch de beste methode, of is er iets eleganters te bedenken ?

Verwijderd

Ik snap er geen ruk van, wat hebben
code:
1
2
3
struct Point { int x, y; };

void f (Point & p); // vult p's x en y in

en
code:
1
2
3
4
5
6
7
struct A { A (int x, int y); };

struct B
{
  A a;
  B ();
};

nou met elkaar te maken, dat wordt mij niet helemaal duidelijk... maar goed, toch maar een poging doen.. Als je dus dat Point structje naar een gelijke A struct wil plaatsen in de constructor van B (maar hoe kom je daar dan aan die point struct??) en hijs precies hetzelfde (dus A==Point) dan kan je gewoon een memcpy doen lijkt me.
Maar waarom zet je dan niet gewoon een Point struct ipv A in B???
't zal wel aan mij liggen, maar k snap t niet helemaal geloof ik...

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
code:
1
B::B() { f(&a); }

toch gewoon? :?

Verwijderd

Op woensdag 01 mei 2002 21:16 schreef marcusk het volgende:
code:
1
B::B() { f(&a); }

toch gewoon? :?
Ehh, klopt niet, ten eerste is a geen Point en verwacht f ook geen pointer maar een referentie...

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Weet je van tevoren al de coordinaten? Worden die meegegeven aan de constructor?

Wil je zoiets als dit :?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Point { int x, y; };
void f (Point & p); // vult p's x en y in
struct A 
{ 
A (int x, int y);
A (const Point p}
{ x = p.x; y = p.y; }
}

struct B
{
  A a;
  B(const Point &p) : a(p) { }
};

int main()
{
   Point tmpPoint;
   f(tmpPoint);
   B(tmpPoint);
}

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 21:09 schreef hondass50 het volgende:
Ik snap er geen ruk van, wat hebben
code:
1
2
3
struct Point { int x, y; };

void f (Point & p); // vult p's x en y in

en
code:
1
2
3
4
5
6
7
struct A { A (int x, int y); };

struct B
{
  A a;
  B ();
};

nou met elkaar te maken, dat wordt mij niet helemaal duidelijk...
Ik wil B's a member object in B::B() initialiseren met de coordinaten die in een Point worden ingevuld door een f call.
maar goed, toch maar een poging doen..
Ik snap weer geen ruk van de rest van jouw bericht :).

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 21:20 schreef Orphix het volgende:
Weet je van tevoren al de coordinaten? Worden die meegegeven aan de constructor?

Wil je zoiets als dit :?

[..]
Nee. Een nieuwe contructor aan A toevoegen is geen optie, B's constructor behoeft geen parameters, en f gebruikt de bestaande waarde van z'n p parameter niet.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op woensdag 01 mei 2002 21:27 schreef Sneechy het volgende:

[..]

Nee. Een nieuwe contructor aan A toevoegen is geen optie, B's constructor behoeft geen parameters, en f gebruikt de bestaande waarde van z'n p parameter niet.
De A en f zitten dus in een extern systeem en je gebruikt f om informatie uit dat systeem te halen dus. (operator = overloaden zal dus ook wel geen optie zijn).

Dan zou ik het idd met een temp object doen, maar dan hoef je nog geen pointers te gebruiken imo. Je kan toch zoiets doen als dit:
code:
1
2
3
4
5
6
B()
{
   static Point p;
   f(p);
   a = A(p.x, p.y);
}

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 21:32 schreef Orphix het volgende:

[..]

De A en f zitten dus in een extern systeem en je gebruikt f om informatie uit dat systeem te halen dus.
In het voorbeeld heb ik inderdaad alleen controle over B (sorry voor de onduidelijkheid).
Dan zou ik het idd met een temp object doen, maar dan hoef je nog geen pointers te gebruiken imo. Je kan toch zoiets doen als dit:
code:
1
2
3
4
5
6
B()
{
   static Point p;
   f(p);
   a = A(p.x, p.y);
}
Dit is onmogelijk omdat A(int x, int y) A's enige contructor is, en B's a dus in B::B()'s initialiser-list geinitialiseert dient te worden

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op woensdag 01 mei 2002 21:40 schreef Sneechy het volgende:
Dit is onmogelijk omdat A(int x, int y) A's enige contructor is, en B's a dus in B::B()'s initialiser-list geinitialiseert dient te worden
Tja als het niet zo'n grote struct betreft dan zou ik gewoon 0-tjes in vullen, dus
code:
1
2
3
B() : a(0,0)
{
}

Verwijderd

Op woensdag 01 mei 2002 21:49 schreef Orphix het volgende:

[..]

Tja als het niet zo'n grote struct betreft dan zou ik gewoon 0-tjes in vullen, dus
code:
1
2
3
B() : a(0,0)
{
}
Owww, was dat het probleem....nou dat werd ook niet echt duidelijk uit je eerste vraag!

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 21:49 schreef Orphix het volgende:

[..]

Tja als het niet zo'n grote struct betreft dan zou ik gewoon 0-tjes in vullen, dus
code:
1
2
3
B() : a(0,0)
{
}
Dit is helaas ook geen optie als A's constructor de gegeven parameters niet alleen opslaat, maar ook verder gebruikt voor z'n initialisatie..

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 22:02 schreef hondass50 het volgende:
Owww, was dat het probleem....nou dat werd ook niet echt duidelijk uit je eerste vraag!
Sorry, ik ben echt heel slecht in het verwoorden van mn programmeer-vraagstukken :'(..

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op woensdag 01 mei 2002 22:27 schreef Sneechy het volgende:

[..]

Dit is helaas ook geen optie als A's constructor de gegeven parameters niet alleen opslaat, maar ook verder gebruikt voor z'n initialisatie..
Umh okay, dan zou idd met pointers werken wel een goede oplossing zijn. Je kan natuurlijk ook nog met static functies die een B maken en waarbij je dus een protected constructor in B hebt (soort van classfactory). Maar ik denk dat je wel wegkomt met de pointer versie ;)

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 22:36 schreef Orphix het volgende:

[..]

Umh okay, dan zou idd met pointers werken wel een goede oplossing zijn. Je kan natuurlijk ook nog met static functies die een B maken en waarbij je dus een protected constructor in B hebt (soort van classfactory). Maar ik denk dat je wel wegkomt met de pointer versie ;)
Sja, dat moet dan maar...

Ik begin die constructor initializer lists eigenlijk steeds minder te waarderen; ze zijn nogal inflexibel omdat je per data member constructor parameter maar één expressie tot je beschikking hebt ;(...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Sneechy: ze zijn nogal inflexibel omdat je per data member constructor parameter maar één expressie tot je beschikking hebt ;(...
wat is er dan gebeurd met dit soort expressies:
code:
1
i = (blaat = 3, aars = 5 * blaat, 2 + aars);

okee, ik geef toe dat dat niet de mooiste code is, maar het kan wel :)

ps: i is dus nu 17 :)

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

Topicstarter
Op woensdag 01 mei 2002 23:24 schreef .oisyn het volgende:
wat is er dan gebeurd met dit soort expressies:
code:
1
i = (blaat = 3, aars = 5 * blaat, 2 + aars);
Ook dat soort expressies zijn extreem beperkt (in dit geval bieden ze bijvoorbeeld geen oplossing).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

dat is waar, maar dan kun je wel creatief zijn en voor ingewikkeldere expressies kleine functies maken, die je vervolgens weer in dit soort expressies gebruikt

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.


  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op woensdag 01 mei 2002 23:35 schreef Sneechy het volgende:
Ook dat soort expressies zijn extreem beperkt (in dit geval bieden ze bijvoorbeeld geen oplossing).
Hmm maar met die constructie kan je dus wel functies aanroepen? Dit kwam ik tegen op google:
BaseSpong ((doThis(), doThat(), doTheOther(), i))
Let op de extra haakjes. Ik heb er geen ervaring mee, maar kan je hiermee geen (statische) functie maken die een Point teruggeeft? Als je dit doorgeeft aan een andere (private) constructor kan je die waardes direct in a zetten. Zoiets als dit wordt het dan
code:
1
2
3
4
5
6
private:
B(const Point &p) : a(p.x, p.y)
{ .. }
public
B() : a((eenFunctieDiePointRetourneert()))
{ // verder niks }

Geen idee of het werkt :P

Verwijderd

Op woensdag 01 mei 2002 23:24 schreef .oisyn het volgende:

wat is er dan gebeurd met dit soort expressies:
code:
1
i = (blaat = 3, aars = 5 * blaat, 2 + aars);

okee, ik geef toe dat dat niet de mooiste code is, maar het kan wel :)

ps: i is dus nu 17 :)
.oisyn kun je dit nader uitleggen? want deze pascal-progger valt bijna van zijn stoel.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Orphix: in jouw voorbeeld zijn die extra haakjes niet eens nodig, je kunt dan wel gewoon een functie aanroepen

die (a, b, c, d, ..., z) constructies leveren z af als resultaat, met a, b, c enz. als tussenexpressies. Als je alleen maar z wil hebben (zoals jij in je voorbeeld doet), dan kun je die haakjes ook wel gewoon weglaten :)

borganism: als je zoiets hebt:
code:
1
i = (a = 2, b = 3 + a, 4 * b);

dan worden de expressies tussen de haakjes uitgevoerd, en de laatste expressie is de return-waarde. In principe kun je dit dus lezen als
code:
1
2
3
4
5
6
7
8
int f ()
{
    a = 2;
    b = 3 + a;
    return 4 * b;
}

i = f ();

behalve dan dat de scope van de variabelen allemaal hetzelfde is

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

Topicstarter
Op woensdag 01 mei 2002 23:38 schreef .oisyn het volgende:
dat is waar, maar dan kun je wel creatief zijn en voor ingewikkeldere expressies kleine functies maken, die je vervolgens weer in dit soort expressies gebruikt
Ook met hulpfuncties blijven dit soort expressies te beperkt voor gevallen als deze, omdat ze geen toegang hebben tot elkaars variabelen. In dit voorbeeldgeval zouden beide expressies eenzelfde Point object moeten kunnen benaderen, en dat kan alleen maar door dit object extern (vanuit het perspectief van de expressies) op te slaan.

Verwijderd

code:
1
i = (blaat = 3, aars = 5 * blaat, 2 + aars);

<offtopic>
Leuk, creatief, en 't heeft zeker zijn toepassingen, maar toch heb ik er persoonlijk een hekel aan als men dit soort constructies te veel gebruikt; het scoort vaak nogal laag op een nogal belangrijk punt: leesbaarheid :)
</offtopic>

Verwijderd

Topicstarter
Op woensdag 01 mei 2002 23:44 schreef Orphix het volgende:
Ik heb er geen ervaring mee, maar kan je hiermee geen (statische) functie maken die een Point teruggeeft? Als je dit doorgeeft aan een andere (private) constructor kan je die waardes direct in a zetten.
Hmm, ik ben niet overtuigd :). Kun je misschien een wat concretere (werkende..) implementatie van B::B() met jouw methode geven?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:48

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 01 mei 2002 23:56 schreef Qlone het volgende:
code:
1
i = (blaat = 3, aars = 5 * blaat, 2 + aars);

<offtopic>
Leuk, creatief, en 't heeft zeker zijn toepassingen, maar toch heb ik er persoonlijk een hekel aan als men dit soort constructies te veel gebruikt; het scoort vaak nogal laag op een nogal belangrijk punt: leesbaarheid :)
</offtopic>
ik deel jouw mening :Y)

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

Topicstarter
Op donderdag 02 mei 2002 00:00 schreef .oisyn het volgende:

[..]

ik deel jouw mening :Y)
En ik ook :).

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-09 00:49
code:
1
2
3
4
5
6
7
8
9
10
struct myPoint : private Point 
{
  myPoint() { f(*this); }
  A CreateA() const { return A(x,y); }
};

class B {
  A a;
  B() : A (myPoint().CreateA() ) ()
};

En omdat de functie bodies in de class staat en elk 1 regel zijn, wordt alles waarschijnlijk inlined. Dus 't is net zo snel als minder nette hacks.

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

Topicstarter
Op donderdag 02 mei 2002 10:38 schreef MSalters het volgende:
code:
1
2
3
4
5
6
7
8
9
10
struct myPoint : private Point 
{
  myPoint() { f(*this); }
  A CreateA() const { return A(x,y); }
};

class B {
  A a;
  B() : A (myPoint().CreateA() ) ()
};

En omdat de functie bodies in de class staat en elk 1 regel zijn, wordt alles waarschijnlijk inlined. Dus 't is net zo snel als minder nette hacks.
Dit lijkt me inderdaad een goede optie (hoewel ik er dan een (static member) functie van zou maken).

Gelukkig is er ook in mijn praktische situatie een public copy constructor beschikbaar, dus het wordt zo'n helper functietje. Dank :).

Trouwens even uit nieuwsgierigheid: kan je je vinden in mijn gevoelens over de inflexibiliteit van constructor initialiser lists ?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-09 00:49
Op donderdag 02 mei 2002 12:03 schreef Sneechy het volgende:

Trouwens even uit nieuwsgierigheid: kan je je vinden in mijn gevoelens over de inflexibiliteit van constructor initialiser lists ?
Beetje.
't Is inderdaad een PITA met legacy interfaces ( void f(T&) ). Maar als je zelf je interfaces ontwerpt is het geen probleem. Vandaar ook mijn oplossing om door inheritance een dunne interface te wrappen om de bestaande onbruikbare.

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

Pagina: 1