CannibalSmith ([info]cannibalsmith) rakstīja [info]koderi kopienā,
@ 2008-01-07 13:12:00

Previous Entry  Add to memories!  Tell a Friend!  Next Entry
C++: cirkulārā iekļaušana
Kāpēc, ja es veicu cirkulāru iekļaušanu, kompilators vairs neatpazīst tipus? Kā panākt, lai B klases objekti spētu operēt ar A klases objektiem?
A.h
#pragma once // ļauj failu iekļaut tikai vienreiz. ķipa #ifndef __A_H__ bla bla
#include "B.h"
class A
{
public:
    B b; // syntax error : missing ';' before identifier 'b'
};

B.h
#pragma once
#include "A.h" // ja šo rindu atkomentētu, kods nokompilētos
class B { };

main.cpp
#include "A.h"
int main()
{
    A a;
    return 0;
}

Risinājums

B.h failā neiekļaut A.h, bet veikt forward deklarāciju un izvākt no B.h visas lietas, kam ir nepieciešama A klases definīcija (piemēram, metožu izsaukumi inline funkcijās). Tad B.cpp failā iekļaut nevis B.h, bet A.h.


(Ierakstīt jaunu komentāru)


[info]zverj
2008-01-07 13:15 (saite)
A.h ieraksti

class B;

(Atbildēt uz šo) (Diskusija)


[info]cannibalsmith
2008-01-07 13:20 (saite)
error C2079: 'A::b' uses undefined class 'B'

(Atbildēt uz šo) (Iepriekšējais)


[info]314
2008-01-07 13:26 (saite)
A.h:

#ifndef __A_H__
#define __A_H__

#include "B.h"
class A
{
public:
B b; // syntax error : missing ';' before identifier 'b'
};
#endif

B.h:

#ifndef __B_H__
#define __B_H__

#include "A.h"
class B { };

#endif

(Atbildēt uz šo) (Diskusija)


[info]cannibalsmith
2008-01-07 13:30 (saite)
Es jau tā daru (ar Visual Studio piedāvāto #pragma once). Piemērā īsuma pēc neieliku.

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]314
2008-01-07 13:42 (saite)
Pamēģini ar ifndef/define.

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]cannibalsmith
2008-01-07 13:46 (saite)
Pamēģināju. Nekā.

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]314
2008-01-07 13:50 (saite)
Ar GCC strādā.

(Atbildēt uz šo) (Iepriekšējais)


[info]bubu
2008-01-07 17:38 (saite)
Kāpēc tev failā B.h vajag iekļaut failu A.h ? Ja tāpēc, lai lietotu klasi A kautkādos funkciju argumentus - tad tu varēsi tur tikai lietot referenci uz klasi A vai pointeri uz klasi A, bet ne parastu klases A objektu. Kompilatoram vajag zināt A klases izmēru baitos, lai nokompilētu tās objekta izmantošanu. Referencei un pointeriem nevajag - tie vienmēr ir 4 baiti.

Ja tas der, tad B.h būtu jāizskatās šādi:
B.h
#pragma once
class A;
class B {

  void func1(A&); // ok, reference
  void func2(A*); // ok, pointeris
  //void func3(A); // slikti, objekts!
};



(Atbildēt uz šo) (Diskusija)


[info]cannibalsmith
2008-01-07 17:52 (saite)
Pilnīgi pareizi. Un tad es B.cpp rakstu
#include "A.h"
void B::func1(A& a)
{
    a.izmantojamMetodi();
}
void B::func2(A* a)
{
    a->getSet();
}

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]bubu
2008-01-07 18:25 (saite)
Tādā gadījumā es tā arī īsti nesapratu - kas tev tur nestrādā?

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]cannibalsmith
2008-01-07 18:27 (saite)
Tagad jau viss strādā. Man šis triks ir jaunatklājums. :)

(Atbildēt uz šo) (Iepriekšējais)


Neesi iežurnalējies. Iežurnalēties?