[c++] pointer to class in initialization list

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • TheWickedD
  • Registratie: Juli 2002
  • Laatst online: 02-04-2024
Hoi, Ik heb flink gegoogled, maar geen antwoord kunnen vinden. Ik hoop dat jullie mij hiermee kunnen helpen.

Onderstaande code compiled prima, maar at runtime blijken de pointers naar niets te wijzen.

Moet ik pointers anders toewijzen in een initialization list, of gaat er iets fout met het doorpasen van de argumenten van de derived naar de base class? Of doe ik nog iets anders fout hier?

Ik gebruik MSVC9 op windows XP.

Bedankt!

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// forward declarations
class CGfx;
class CData;


// derived
class CExecutiveKeyboard : public CExecutive
{
public:
    CExecutiveKeyboard(CData* pcData_, CGfx* pcGfx_);
    ~CExecutiveKeyboard(void);
};

CExecutiveKeyboard::CExecutiveKeyboard(CData* pcData_, CGfx* pcGfx_) : CExecutive(pcData_, pcGfx_)
{
}

CExecutiveKeyboard::~CExecutiveKeyboard(void)
{
}


//base
class CExecutive
{
public:
    CExecutive(CData* pcData_, CGfx* pcGfx);
    ~CExecutive(void);

protected:
    CData* _pcData;
    CGfx*  _pcGfx;
};

CExecutive::CExecutive(CData* pcData_, CGfx* pcGfx_) : _pcData(pcData_), _pcGfx(pcGfx_)
{
}

CExecutive::~CExecutive(void)
{
}


//main
int main(int argc, char* argv[])
{
    // initialize class instances
    CData               cData;
    CGfx                cGfx;
    CExecutiveKeyboard  cE(&cData, &cGfx);

    return 1;
}

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:02
Je gebruikt de pointers( of het object for that matter ) verder niet dus het zou kunnen zijn dat je naar een object zit te kijken die geoptimaliseerd is door de compiler.
Kans is dat op de regel met de return je cE variabele al niet meer is wat je zou verwachten.

[edit]
Kon ook niets raars vinden eigenlijk, vandaar dat ik bovenstaande opmerking maak.

[ Voor 15% gewijzigd door farlane op 20-07-2009 15:41 ]

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.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 00:02
TheWickedD schreef op maandag 20 juli 2009 @ 12:47:
Onderstaande code compiled prima, maar at runtime blijken de pointers naar niets te wijzen. [..]
Moet ik pointers anders toewijzen in een initialization list, of gaat er iets fout met het doorpasen van de argumenten van de derived naar de base class? Of doe ik nog iets anders fout hier?
Je code lijkt me zo op het oog goed. Waaruit blijkt volgens jou dat" de pointers naar niets wijzen"?

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik denk eerder dat je cData en cGfx ergens uit scope gaan en opgeruimd worden terwijl er wel nog pointers naar wijzen... maar het is gokken want de code boven lijkt me wel goed.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Foo {
// ...
int x;
};

Foo* g_foo;

void init() {
   Foo foo;
   g_foo = &foo;
   // scope exit, foo wordt destructed, g_foo dangled
}

int main() {
   init();
   g_foo->x; // error, g_foo is een dangling pointer
  return 0;
}

[ Voor 43% gewijzigd door Zoijar op 20-07-2009 15:54 ]


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Je bovenstaand programma doet "niks", misschien met je een "debug" versie maken om alle code ook daadwerkelijk te laten uitvoeren (de optimizer kan main compilen naar "mov eax, 1" zonder dat het een probleem oplevert :p)

Welke compiler gebruik je, met welke configuratie? Wat exact bedoel je met "niets"? Zet eens een breakpoint op de derde regel van main, en inspecteer cData en cGfx, wat zie je dan?

Sidenote:
Daarnaast mist er best wat informatie, wat jij daar hebt staan gaat nooit compilen (je derived van een base die nog niet gedeclareerd is, in main instantieer je ongedefinieerde classes CGfx en CData, dus je laat nu iets essentieels achter waarschijnlijk :P)

[ Voor 25% gewijzigd door MLM op 20-07-2009 21:07 ]

-niks-


Acties:
  • 0 Henk 'm!

  • TheWickedD
  • Registratie: Juli 2002
  • Laatst online: 02-04-2024
Bedankt voor jullie reacties. Mijn post is te snel geweest. Ik heb heel snel uit de losse hand een simpele testcase van mijn setup in elkaar gezet, sorry dat die inderdaad niet compileerde.

Ik heb werkende code in een project waar ik geen initialization list gebruik maar de assignment in de body van de constructor heb staan. Toen ik over initialization lists leerde (ik was boost documentatie aan het lezen en kwam syntax tegen die ik niet kende) besloot ik dit in te bouwen, omdat het (1) de correcte manier is om mijn variabelen te initializeren en (2) ik het niet erg vind mijn code tijdelijk te breken om ervan te leren.

Nu werkt het niet in mijn grote project (mijn class pointer is NULL, niet dangling) met nog een hele zooi andere classes en natuurlijk een heel stel member functies, maar in mijn simpele testcase (zie code hieronder) werkt het geheel wel :s

Verdomme, ik ben erachter wat er fout zat. Verderop in de initializatiecode bleek ik mijn pointer naar een van de classes weer op NULL te zetten (waarom???). Goed, probleem opgelost dus.

Bedankt voor jullie hulp. code hieronder werkt, misschien dat iemand anders er iets aan heeft.

Ik heb nog een andere vraag (ik heb het hele pointer en reference gedoe nog steeds niet helemaal door): Nu store ik een pointer naar mijn CData class, waardoor ik allemaal nare -> en soms zelfs &(*_pcData)-> syntax heb. Is het mogelijk om de CData class op de een of andere manier bij reference door te geven aan de constructor, zodat ik de CData class zelf (maar niet een kopie!) in mijn CExecutive class kan hebben? dus niet CData* maar CData. Ik kan de CData class niet gewoon in CExecutive zetten omdat ik nog andere classes heb die via een pointer met dezelfde CData instantie praten.

Bedankt!

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// includes
#include <iostream>
#include <string>
using namespace std;

// forward declarations
class CData
{
public:
    CData(void) {};
    ~CData(void) {};

    // retrievers
    const   string& GetTest() const {return _test;}
            string& SetTest()       {return _test;}

private:
    string _test;
};


//base 
class CExecutive
{
public:
    CExecutive(CData* pcData_) : _pcData(pcData_) {};
    ~CExecutive(void) {};

protected:
    CData* _pcData;
};


// derived 
class CExecutiveKeyboard : public CExecutive
{
public:
    CExecutiveKeyboard(CData* pcData_): CExecutive(pcData_) {};
    ~CExecutiveKeyboard(void) {};

    void Print() {cout << _pcData->GetTest().c_str() << endl;};
};


//main 
int main(int argc, char* argv[])
{
    // initialize class instances
    CData               cData;
    CExecutiveKeyboard  cE(&cData);

    // test
    cData.SetTest().assign("test");
    cE.Print();

    // exit
    return 1;
}

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:02
Je kunt ook references als class member hebben maar die moeten dan wel in de initializer list worden gezet. ( Zoals je nu doet dus eigenlijk )
waardoor ik allemaal nare -> en soms zelfs &(*_pcData)-> syntax heb
Als je de -> naar vindt ga je het nog moeilijk krijgen ben ik bang :) Zou je trouwens een voorbeeld kunnen geven waar je de 2e notatie nodig hebt?

[ Voor 45% gewijzigd door farlane op 21-07-2009 09:14 ]

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.


Acties:
  • 0 Henk 'm!

  • TheWickedD
  • Registratie: Juli 2002
  • Laatst online: 02-04-2024
Hi farlane,

Bedankt voor de simpele tip, ik zal wel te complex aan het denken zijn geweest.

Hieronder mijn code die werkt met references. Aangezien ik hiervan wil leren, mocht iemand nog tips hebben dan hoor ik het graag!

Bedankt!

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// includes
#include <iostream>
#include <string>
using namespace std;

// forward declarations
class CData
{
public:
    CData(void) {};
    ~CData(void) {};

    // retrievers
    const   string& GetTest() const {return _test;}
            string& SetTest()       {return _test;}

private:
    string _test;
};


//base 
class CExecutive
{
public:
    CExecutive(const CData& rcData_) : _rcData(rcData_) {};
    ~CExecutive(void) {};

protected:
    const CData& _rcData;
};


// derived 
class CExecutiveKeyboard : public CExecutive
{
public:
    CExecutiveKeyboard(const CData& _rcData): CExecutive(_rcData) {};
    ~CExecutiveKeyboard(void) {};

    void Print() {cout << _rcData.GetTest().c_str() << endl;};
};


//main 
int main(int argc, char* argv[])
{
    // initialize class instances
    CData               cData;
    CExecutiveKeyboard  cE(cData);

    // test
    cData.SetTest() = "test";
    cE.Print();

    // exit
    return 1;
}

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

References en pointers zijn in principe hetzelfde beestje*, alleen is de syntaxis iets anders. Bij references gebruik je . voor memberaccess, bij pointers gebruik je ->. Het is persoonlijke keuze wat je lekkerder vind werken.

Gebruik je veel classes met operator overloads, dan kan je beter voor references gaan, anders krijg je lelijke stuff zoals "(*ptr) <op> arg", of nog mooier; "ptr->operator <op>(arg)" ;)

*) behalve dat de compiler bij een reference vereist dat een reference altijd naar een bestaand object verwijst, maar het functioneerd hetzelfde :p

[ Voor 19% gewijzigd door MLM op 21-07-2009 09:30 ]

-niks-


Acties:
  • 0 Henk 'm!

  • TheWickedD
  • Registratie: Juli 2002
  • Laatst online: 02-04-2024
Hoi MLM,

Bedankt voor je reactie. Ik heb in mijn code nu zoveel mogelijk pointers vervangen door references.

Zo heb ik bijvoorbeeld een (void) convolutie functie die zijn output schreef naar "vector<double>* pvOut_". Dit heb ik nu vervangen met "vector<double>& rvOut_". Dit zorgt voor een schonere syntax in de function body, maar het lijkt ook dat de functie een stuk sneller is geworden.

Heeft het gebruik van een reference dus nog meer pluspunten dan dat de compiler een extra restrictie op het gebruik ervan heeft?

Ik zal eens testen of dit echt sneller is, tenzij jullie zeggen dat dit logisch is. Ik heb in een andere functie in mijn code een vector's [] operator vervangen door een iterator, misschien dat het (subjectieve) verschil in snelheid daarvandaan komt.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Zoijar schreef op maandag 20 juli 2009 @ 15:51:
Ik denk eerder dat je cData en cGfx ergens uit scope gaan en opgeruimd worden terwijl er wel nog pointers naar wijzen... maar het is gokken want de code boven lijkt me wel goed.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Foo {
// ...
int x;
};

Foo* g_foo;

void init() {
   Foo foo;
   g_foo = &foo;
   // scope exit, foo wordt destructed, g_foo dangled
}

int main() {
   init();
   g_foo->x; // error, g_foo is een dangling pointer
  return 0;
}
Waarom wordt foo gedestructed? Moet je dat niet zelf doen in C++ ? En hoe moet je dan dit oplossen om er voor te zorgen dat g_foo naar foo blijft verwijzen?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Snake schreef op dinsdag 21 juli 2009 @ 10:34:
Waarom wordt foo gedestructed? Moet je dat niet zelf doen in C++ ? En hoe moet je dan dit oplossen om er voor te zorgen dat g_foo naar foo blijft verwijzen?
Omdat foo op de stack staat. Ik verwijs even hier naar: http://www.learncpp.com/c...9-the-stack-and-the-heap/

Als je het anders wilt moet je hem op de heap alloceren, met een operator new. Maar dan moet je hem ook weer opruimen.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Zoijar schreef op dinsdag 21 juli 2009 @ 10:49:
[...]

Omdat foo op de stack staat. Ik verwijs even hier naar: http://www.learncpp.com/c...9-the-stack-and-the-heap/

Als je het anders wilt moet je hem op de heap alloceren, met een operator new. Maar dan moet je hem ook weer opruimen.
Dus als ik het goed begrijp moet je dan: g_foo = new &foo; doen?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Snake schreef op dinsdag 21 juli 2009 @ 10:56:
[...]

Dus als ik het goed begrijp moet je dan: g_foo = new &foo; doen?
Nee. Je krijgt dan gewoon g_foo = new Foo();

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

R4gnax schreef op dinsdag 21 juli 2009 @ 11:59:
[...]


Nee. Je krijgt dan gewoon g_foo = new Foo();
Maar hoe point je dan die g_foo naar de oude &foo? Moet je alle properties handmatig kopieren?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

No offence, maar dat zijn echt hele algemene C++ dingen; als je dat allemaal goed wilt weten, dan raad ik je aan om er gewoon een C++ boek bij te pakken waar dat allemaal haarfijn in staat uitgelegd. :)

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Zoijar schreef op dinsdag 21 juli 2009 @ 13:54:
No offence, maar dat zijn echt hele algemene C++ dingen; als je dat allemaal goed wilt weten, dan raad ik je aan om er gewoon een C++ boek bij te pakken waar dat allemaal haarfijn in staat uitgelegd. :)
Laat ik mij dan ook bezig houden met C# en C# only. Ik wil wel C++ leren, maar ik vind de overstap nog wat te groot.

Daarom dat ik dat hier vraag ;)

Going for adventure, lots of sun and a convertible! | GMT-8

Pagina: 1