Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

11.07.2008, 10:43

Probleme bei kreuzendem include

Hi, ich weiß der Titel ist nicht 100%ig richtig aber ein besserer ist mir nicht eingefallen.

Aus C# und Java bin ich gewöhnt das ich von allen Klassen Zugriff auf alle anderen Klassen haben. Jetzt brauche ich das in C++ auch und bin auf folgendes Problem gestoßen.

Wenn ich alles überall includiere gibt es logischerweise eine Mehrfachdefinition und einen Kompilerfehler. Also dachte ich mir baue ich einen includeguard herum. Jetzt bekomme ich in den Dateien welche die ebtsprechende Datei nicht als erstes includieren den Fehler das die Klasse nicht bekannt ist. Selbes Problem mit #pragma once.

Hier mal ein Beispiel

Zitat von »"main.cpp"«


#pragma once

#include "classA.cpp"
#include "classB.cpp"

int main(int argc, char** args)
{
A a;
B b;

a.b = &b;
b.a = &a;

return 0;
}


Zitat von »"classA.cpp"«


#pragma once

#include "classB.cpp"

class A
{
public:
B* b; // Fehler, Klasse B ist nicht bekannt
};


Zitat von »"classB.cpp"«


#pragma once

#include "classA.cpp"

class B
{
public:
A* a; // Fehler, Klasse A ist nicht bekannt
};


Kann mir jemand sagen wo hier mein Gedankenfehler liegt? Ich bin da für jeden Hinweis dankbar

Wäre vieleicht auch fas für die faq


Grüße

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

11.07.2008, 10:54

Normal verwendet man hierfür das Pimpl-Idiom.

classA.h:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
#pragma once

class B;

class A
{
public:
  B* b;
};


classB.h:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
#pragma once

class A;

class B
{
public:
  A* a;
};


classA.cpp:

C-/C++-Quelltext

1
2
3
4
#include "classA.h"
#include "classB.h"

// definition


classB.cpp:

C-/C++-Quelltext

1
2
3
4
#include "classB.h"
#include "classA.h"

// definition


main.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
#include "classA.h"
#include "classB.h"

int main()
{
  A a;
  B b;

  a.b = &b;
  b.a = &a;
}
@D13_Dreinig

3

11.07.2008, 13:34

Also Inclusionguards mache ich immer mit:

Quellcode

1
2
3
4
#ifndef _CLASS_H_
#define _CLASS_H_

#endif


Desweiteren koennte eine die Vorwaertsdeklaration helfen, hat aber nichts mit dem Pimpl-Idiom zu tun.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

11.07.2008, 14:07

Bezeichner die mit einem underscore gefolgt von einem Großbuchstaben beginnen sind afaik reserviert...

5

11.07.2008, 14:18

Das wär mir neu dot. Ich verwende auch das von knivil genannte Schema.
Noch nie Probleme damit...

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

11.07.2008, 14:37

Zitat von »"TrikkieMikkie"«

Das wär mir neu dot. Ich verwende auch das von knivil genannte Schema.
Noch nie Probleme damit...


Das du nie Probleme damit hast heißt nicht, dass man das auch machen darf!

Zitat von »"ISO/IEC 14882:2003(E) 17.4.3.1.2 [lib.global.names«

Global names"]
-1- Certain sets of names and function signatures are always reserved to the implementation:

* Each name that contains a double underscore ("__") or begins with an underscore followed by an uppercase letter (lex.key) is reserved to the implementation for any use.

* Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.*

[Footnote: Such names are also reserved in namespace ::std (lib.reserved.names). --- end foonote]

@D13_Dreinig

7

11.07.2008, 14:42

War mir wie gesagt neu David_pb.
Da ich aber lernfähig und wissbegierig bin (und ein braver Progger), werde ich das Schema wohl noch mal überdenken. ;)

8

11.07.2008, 17:30

Danke David_pb und alle die sich dem Problem angenommen haben.

Wenn man viel mit C# und Java arbeitet muss man echt aufpassen das man nicht die Basics von C++ vergisst :D

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

11.07.2008, 17:49

Zitat von »"chriss"«


Wenn man viel mit C# und Java arbeitet muss man echt aufpassen das man nicht die Basics von C++ vergisst :D


Ohja! ;)
@D13_Dreinig

10

11.07.2008, 18:22

Ich komm mir jetzt echt bescheuert vor aber wie funktioniert das jetzt mit den Methoden?
David_pbs Methode funktioniert soweit, dass ich jetzt alle Klassen überall haben kann.

Versuche ich jetzt eine Methode aufzurufen bekomme ich eine Meldung, dass der linke Teil eine Klasse/Struktur/Union sein muss.

Ich dachte ich wäre schlau und habe folgendes versucht

C-/C++-Quelltext

1
2
3
4
class A
{
 void func();
};


das ging leider genauso wenig wie

C-/C++-Quelltext

1
2
3
4
class A
{
 virtual void func()=0;
};



Das Letztere ist ja eigentlich eh falsch, da ich ja keinen Prototypen für eine virtuelle Funktion haben will ( war nur ein Test ), aber bei dem Ersten wäre ich davon ausgegangen das es geht.

Als Letztes hatte ich folgendes versucht

C-/C++-Quelltext

1
2
3
class A;

void A::func();

was aber auch nichts geändert hat.
gibt es denn noch eine Möglichkeit?

EDIT: Wenn ich mir die ersten beiden Varianten so ansehen habe ich da eigentlich schon die Klasse implementiert, nur das die Funktionen keinen Body haben. Was kann man denn noch machen?

Werbeanzeige