[C++] Probleem met twee classes die elkaar includen

Pagina: 1
Acties:

  • pinkwin|IA
  • Registratie: Juni 2003
  • Laatst online: 23-04-2004
Bij het maken van een SDI applicatie in MS visual C++ worden een aantal bestanden automatisch gegenereerd. Onder deze: testDoc.cpp en testView.cpp en van beide ook de .h bestanden.

Mijn probleem is, in de testView moet ik een instantie van testDoc hebben en andersom ook. In een voorbeeld applicatie hebben ze hetzelfde probleem opgelost door de TestDoc.h te voorzien van een soort van 'class declaratie regel':
code:
1
2
3
4
5
6
7
8
9
10
11
12
//TestDoc.h 
class CTestView; 

classCTestDoc: public CDocument{ 
protected: 
  CTestDoc(); 
  DECLARE_DYNCREATE(CTestDoc) 

public: 
  CTestView m_testView; 
  virtual ~CTestDoc(); 
....

Als ik dit probeer in mijn applicatie, krijg ik de C2079 error:
m_testView uses undefined class 'CTestView'.
Msdn zegt over deze error: "The specified identifier was declared as a class, structure, or union that was not defined."

Die error krijg ik op deze regel:
code:
1
CTestView m_testView

Heeft iemand een idee hoe ik dit oplos?

Iemand heeft me al aangeraden om aan het begin van de .h files: #ifndef, #define en onderaan #endif te zetten, maar deze regels code zet ms vc++ zelf al om de .h files heen..

Ik zeg maar zo, ik zeg maar nix. dan zeg ik al veel te veel.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17

Voor zover ik weet kan een class in C++ geen object (instance) van zichzelf als member hebben.
Je kan dit wel oplossen door ipv een instance van dat object bij te houden, een pointer naar dat object bij te houden:
[code]
public:
CTestView* m_TestView;[/code]

(Dan moet je natuurlijk wel nog code schrijven om te alloceren enzo)


Ik zie nu dat je die m_TestView een member maakt van een andere class, dat werkt natuurlijk wel zonder pointers.

Heb je de juiste header ge-included? (Die waarin de class CTestView gedefinieerd is? )

[ Voor 25% gewijzigd door whoami op 12-06-2003 09:44 ]

https://fgheysels.github.io/


  • Obliterator
  • Registratie: November 2000
  • Laatst online: 22-08 11:32
Het is al een tijd geleden dat ik Model-View-Controller architectuur 'geleerd' heb, maar het lijkt mij erg onlogisch dat de Doc een instantie van een view bij zich heeft. Het hele idee is toch dat er meerder views kunnen zijn op een doc? Dat kan nu dus niet meer.

  • The End
  • Registratie: Maart 2000
  • Laatst online: 13:32

The End

!Beginning

whoami schreef op 12 June 2003 @ 09:43:

Voor zover ik weet kan een class in C++ geen object (instance) van zichzelf als member hebben.
Je kan dit wel oplossen door ipv een instance van dat object bij te houden, een pointer naar dat object bij te houden:
[code]
public:
CTestView* m_TestView;[/code]

(Dan moet je natuurlijk wel nog code schrijven om te alloceren enzo)


Ik zie nu dat je die m_TestView een member maakt van een andere class, dat werkt natuurlijk wel zonder pointers.

Heb je de juiste header ge-included? (Die waarin de class CTestView gedefinieerd is? )
Hij heeft 2 verschillende classes. (CTestDoc en CTestView)

Ik had hetzelfde probleem en ik heb het opgelost door dit te doen:
code:
1
2
3
4
5
class MyClass;

#include "MyClass.h"

//Nu kan je hem hier gebruiken

  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17
Obliterator schreef op 12 juni 2003 @ 09:47:
Het is al een tijd geleden dat ik Model-View-Controller architectuur 'geleerd' heb, maar het lijkt mij erg onlogisch dat de Doc een instantie van een view bij zich heeft. Het hele idee is toch dat er meerder views kunnen zijn op een doc? Dat kan nu dus niet meer.
Volgens mij zou een Document (subject) een lijst moeten bijhouden van (abstracte) Views (observers) die er op dat moment zijn op dat Document.

Zo kan het document tegen iedere view gaan zeggen: Update eens, want ik ben veranderd.

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17
The End schreef op 12 juni 2003 @ 09:48:
[...]


Hij heeft 2 verschillende classes. (CTestDoc en CTestView)

Ik had hetzelfde probleem en ik heb het opgelost door dit te doen:
code:
1
2
3
4
5
class MyClass;

#include "MyClass.h"

//Nu kan je hem hier gebruiken
Dat bedoelde ik ook. ;)

Echter, volgens mij moet het omgekeerd zijn:
code:
1
2
3
#include "MyClass.h"

class MyClass.h;


Ik vermoed zelfs dat je die class MyClass.h er niet zult mogen zetten. Gaat de compiler dan niet gaan reklameren over multiple types ofzo?
Je hebt nl. al een type MyClass gedefinieerd in die header, en dan ga je het daaronder nog eens gaan definieren.

https://fgheysels.github.io/


  • pinkwin|IA
  • Registratie: Juni 2003
  • Laatst online: 23-04-2004
De juiste headers zijn geinclude, daar ben ik zeker van, maar wat bedoel je precies met:
Ik zie nu dat je die m_TestView een member maakt van een andere class, dat werkt natuurlijk wel zonder pointers
??

Ik zeg maar zo, ik zeg maar nix. dan zeg ik al veel te veel.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17
pinkwin|IA schreef op 12 June 2003 @ 09:52:
De juiste headers zijn geinclude, daar ben ik zeker van, maar wat bedoel je precies met:

[...]
??
Ik dacht eerst dat m_TestView een member was van de klasse CTestView, maar ik zag daarna dat het een member was van de CTestDoc class.
(Moet je trouwens geen spatie zetten tussen class en CTestDoc?)

Toon eens een stukje code mbt die includes?

[ Voor 19% gewijzigd door whoami op 12-06-2003 09:56 ]

https://fgheysels.github.io/


  • The End
  • Registratie: Maart 2000
  • Laatst online: 13:32

The End

!Beginning

whoami schreef op 12 juni 2003 @ 09:52:
[...]

[knip]

Ik vermoed zelfs dat je die class MyClass.h er niet zult mogen zetten. Gaat de compiler dan niet gaan reklameren over multiple types ofzo?
Je hebt nl. al een type MyClass gedefinieerd in die header, en dan ga je het daaronder nog eens gaan definieren.
Je moet zowieso class MyClass (zonder die .h) hebben staan. Ik heb beide versies even geprobeerd (in VC6) en ze werken allebei :)

  • pinkwin|IA
  • Registratie: Juni 2003
  • Laatst online: 23-04-2004
(de ontwikkelcomputer is niet verbonden met het internet, moest het overtikken :D Typo dus..)

Ik zeg maar zo, ik zeg maar nix. dan zeg ik al veel te veel.


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

curry684

left part of the evil twins

Je mag een class pas gebruiken als member in een andere class zodra hij volledig gedefinieerd is (dus niet alleen gedeclareerd). Je moet de definitie van TestView dus includen voordat je TestDoc definieert. Door sequentiele parsing houdt dit vervolgens per definitie in dat je geen TestDoc als member van TestView kunt gebruiken, maar dat is logisch omdat je dan de computer op zou blazen bij instantiatie van 1 van de 2 :) Pointers is dan 'da way to go'.

Professionele website nodig?


  • pinkwin|IA
  • Registratie: Juni 2003
  • Laatst online: 23-04-2004
code:
1
2
3
4
5
6
7
// testView.cpp

#include "stdafx.h"
#include "test.h"

#include "testDoc.h"
#include "testView.h"

code:
1
2
3
4
5
6
7
// testDoc.cpp

#include "stdafx.h"
#include "test.h"

#include "testView.h"
#include "testDoc.h"

In een voorbeeld applicatie (een drive explorer), is dezelfde constructie gebruikt. daar werkt het wel.

[ Voor 33% gewijzigd door pinkwin|IA op 12-06-2003 10:07 ]

Ik zeg maar zo, ik zeg maar nix. dan zeg ik al veel te veel.


  • pinkwin|IA
  • Registratie: Juni 2003
  • Laatst online: 23-04-2004
het probleem is opgelost:
code:
1
CTestView m_testView;

had moeten zijn:
code:
1
CTestView* m_testView;

Ik zag plots dat whoami in zijn eerste bericht dat hij daar een * tussen had staan..
anyway, thnx allemaal :)

Ik zeg maar zo, ik zeg maar nix. dan zeg ik al veel te veel.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

whoami schreef op 12 June 2003 @ 09:52:
Echter, volgens mij moet het omgekeerd zijn:
code:
1
2
3
#include "MyClass.h"

class MyClass.h;


Ik vermoed zelfs dat je die class MyClass.h er niet zult mogen zetten. Gaat de compiler dan niet gaan reklameren over multiple types ofzo?
Je hebt nl. al een type MyClass gedefinieerd in die header, en dan ga je het daaronder nog eens gaan definieren.
hier klopt helemaal niets van. Ten eerste is die declaratie van MyClass (waar een .h achter staat, maar dat zal wel een typfout zijn ;)) na de include niet nodig, maar het geeft ook geen foutmeldingen. Je declareert hier namelijk MyClass, en dat kun je zo vaak doen als je wilt. Een definitie kun je echter maar 1 keer geven, en dat wordt gedaan in MyClass.h

pinkwin: verder kun je de een natuurlijk wel een niet-pointer member laten zijn van de ander. Bijvoorbeel CTestDoc laat je zoals ie is, en in CTestView gebruik je een poiner naar CTestDoc. Dit compilet prima door in TestDoc.h gewoon TestView.h te includen, en in TestView.h de klasse CTestDoc te declareren

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* * * TestView.h * * */
class CTestDoc;

class CTestView
{
    // ...
    CTestDoc * doc;
};


/* * * TestDoc.h * * */
#include "TestView.h"

class CTestDoc
{
    // ...
    CTestView view;
};


verder moet je natuurlijk headerguards in je headers zetten, zodat ze niet meerdere keren geinclude kunnen worden
Bijvoorbeeld:
C++:
1
2
3
4
5
6
#ifndef TESTDOC_H
#define TESTDOC_H

// de header source hier

#endif


Ook moeten headers volledig op zichzelf kunnen staan, en mag je dus niet verwachten dat voordat jouw header geinclude is al een andere header geinclude wordt. Include altijd alles wat je nodig hebt voor die header, en alleen dat wat je nodig hebt.

[ Voor 40% gewijzigd door .oisyn op 12-06-2003 11:46 ]

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.


  • whoami
  • Registratie: December 2000
  • Laatst online: 10:17
Mjah, vandaar dat ik ook zei: ik vermoed dat dat niet mag. Die .h erachter was idd een typo ja.

Maareh, ik blijf weg uit C++ topics. :P

[ Voor 19% gewijzigd door whoami op 12-06-2003 11:40 ]

https://fgheysels.github.io/

Pagina: 1