[C++] GCC lokaal object parameter by-reference probleem

Pagina: 1
Acties:

  • Rukapul
  • Registratie: Februari 2000
  • Laatst online: 23-08 14:24
Ik zit al een tijdje met het volgende probleem, dat de volgende code wel onder VC++ 6 compileert maar niet onder GCC 2.96:
C++:
1
2
3
4
    B b = B(A("blaat"));

test.cpp:181: could not convert `A("blaat")' to `A &'
b.h:44: in passing argument 1 of `B::B (A &)'

Ik moet het dan altijd veranderen in het onderstaande om te laten compileren en dat is een beetje irritant:
C++:
1
2
    A a = A("blaat");
    B b = B(a);

Dit allemaal gegeven de volgende geschoonde class definitions:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A
{
public:
    A(const char *filename);            
    A(const A& rhs);        // copy constructor
    A& operator=(const A& rhs);// assignment operator
};

class B
{
public:
    B(const B& rhs); // copy constructor
    B(A& a);    
    ~B();
    const B& operator=(const B& rhs);   // assignment operator

};

Hoe krijg ik deze code met zo min mogelijk wijzigingen werkend op een regel? Is er een C++ cast oid? Of moet ik gewoon niet by-reference gebruiken? A geef ik liever niet by value door, want dan vind er een memcpy van wat data plaats.

Eigenlijk zie ik het probleem niet zo waarom de eerste optie niet zou werken want hij kan het object gewoon op de lokale stack aanmaken, by-reference doorgeven en daarna opruimen...

[ Voor 34% gewijzigd door Rukapul op 24-03-2003 09:12 ]


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

drm

f0pc0dert

by-reference doorgeven en daarna opruimen...
Zit daar niet je probleem? Beschermt gcc je hier niet gewoon voor een memoryleak? Wanneer 't object daadwerkelijk door B::B() opgeruimd wordt, zou het idd geen probleem moeten zijn, maar ik gok dat 't niet helemaal door gcc begrepen wordt dat je "iets anders" je "eigen rotzooi" op laat ruimen, als je begrijpt wat ik bedoel ;)

Overigens vind ik je motivatie voor 't probleem een beetje vreemd: je wilt per se de code op een regel :?

Een oplossing zou kunnen zijn om een statische "factory" method o.i.d. aan je A class toe te voegen die een reference naar een A object teruggeeft. Roep vervolgens die factory aan als argument van de B-constructor i.p.v. de constructor van A :)

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


  • Rukapul
  • Registratie: Februari 2000
  • Laatst online: 23-08 14:24
drm schreef op 24 March 2003 @ 09:25:
[...]
Zit daar niet je probleem? Beschermt gcc je hier niet gewoon voor een memoryleak?
Nee, want object a wordt lokaal geinstantieerd en aan het einde van de scope (method) opgeruimd normaal gesproken.
Wanneer 't object daadwerkelijk door B::B() opgeruimd wordt, zou het idd geen probleem moeten zijn, maar ik gok dat 't niet helemaal door gcc begrepen wordt dat je "iets anders" je "eigen rotzooi" op laat ruimen, als je begrijpt wat ik bedoel ;)
Nee, B doet er helemaal niets mee (method is ook const), behalve wat get methods aanroepen op A.
Overigens vind ik je motivatie voor 't probleem een beetje vreemd: je wilt per se de code op een regel :?
Het komt op aardig wat plaatsen in de code voor, Java-style zegmaar, en zo moet ik enorm veel tussenvariabelen maken en wordt de code minder duidelijk.
Een oplossing zou kunnen zijn om een statische "factory" method o.i.d. aan je A class toe te voegen die een reference naar een A object teruggeeft. Roep vervolgens die factory aan als argument van de B-constructor i.p.v. de constructor van A :)
B b = B(A.createObj("blaat")) ?
Als ik dat doe dan kan ik het gecreerde object natuurlijk nooit meer opruimen en het gebeurt ook niet meer automatisch aan het einde van de scope.

Verwijderd

Probeer de instantie van "A" eens via een const reference mee tegeven, waarschijnlijk helpt dat...
Indien dat het geval is zie: [rml][ c++] arguments by-reference[/rml]

[ Voor 37% gewijzigd door Verwijderd op 24-03-2003 10:01 ]


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

drm

f0pc0dert

Rukapul:
B b = B(A.createObj("blaat")) ?
Als ik dat doe dan kan ik het gecreerde object natuurlijk nooit meer opruimen en het gebeurt ook niet meer automatisch aan het einde van de scope.
Zit wat in :z

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


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op 24 maart 2003 @ 09:55:
Probeer de instantie van "A" eens via een const reference mee tegeven, waarschijnlijk helpt dat...
Indien dat het geval is zie: [rml][ c++] arguments by-reference[/rml]
Yep, precies. De C++ standaard schrijft voor dat een temporary niet bij (vertaling van by? ;) ) non-const reference gepassed mag worden.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Rukapul schreef op 24 maart 2003 @ 09:40:
Nee, B doet er helemaal niets mee (method is ook const), behalve wat get methods aanroepen op A.
Dat staat er niet hoor, er staat B(A&) en geen B(const A&) dus blijkbaar ga je het A object veranderen. Dat de method const is wil zeggen dat je B niet veranderd.
Als ik dat doe dan kan ik het gecreerde object natuurlijk nooit meer opruimen en het gebeurt ook niet meer automatisch aan het einde van de scope.
Auto pointers gebruiken, en een functie in B die een auto_ptr naar A accepteert. Dan draag je ook meteen expliciet ownership van het A object over naar B.

  • Rukapul
  • Registratie: Februari 2000
  • Laatst online: 23-08 14:24
Verwijderd schreef op 24 maart 2003 @ 09:55:
Probeer de instantie van "A" eens via een const reference mee tegeven, waarschijnlijk helpt dat...
Indien dat het geval is zie: [rml][ c++] arguments by-reference[/rml]
Thx, dat was 'm!
offtopic:
ik had wel wat beter mogen zoeken merk ik
Dat staat er niet hoor, er staat B(A&) en geen B(const A&) dus blijkbaar ga je het A object veranderen. Dat de method const is wil zeggen dat je B niet veranderd.
Je hebt gelijk. Bij de functie stond nog als TODO dat de parameter const moest worden. Bug gefixed, probleem opgelost :)
Pagina: 1