Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Externe Klasse einbinden? (NIVEAU:Anfänger/KOMPLEXITÄT:Niedrig)

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
27.08.2004, 15:47 Uhr
GateKeeper



Hallo.

Ich möchte eine Klasse in einer anderen Quelldatei einbinden, ohne die komplette Deklaration zu übernehmen.

Ist so etwas überhaupt möglich?

Datei1.h:

C++:
class Testklasse {
public:
      int Testwert ;
} ;




Datei2.h:

C++:
extern class Testklasse ; // funktioniert nicht



Füge ich in <Datei2.h> den Prototyp aus <Datei1.h> ein, funktioniert alles einwandfrei. Nur möchte ich die Deklarationen so selten wie möglich kopieren, damit die Quelldatei bei Verwendung umfangreicher Klassen nicht zu unübersichtlich wird.

Bearbeitung von 0xdeadbeef:

MARKTSCHREIER-GESCHREI in normalen Text umgewandelt. Nächstes mal prüfen, ob Caps Lock an ist.


Dieser Post wurde am 27.08.2004 um 16:02 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
27.08.2004, 16:03 Uhr
Pablo
Supertux
(Operator)


Wie wäre es in datei2.h folgende einzufügen?


C++:
#include "Datei1.h"




extern class Testklasse ; // funktioniert nicht kann nicht gehen, weil extern nur für Variablen funktioniert.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.08.2004, 16:04 Uhr
0xdeadbeef
Gott
(Operator)


datei1.h

C++:
#ifndef INCLUDED_DATEI1_H
#define INCLUDED_DATEI1_H

class Testklasse {
public:
  int Testwert;
};

#endif


datei2.h

C++:
#include "datei1.h"

extern Testklasse meine_instanz_von_testklasse;


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.08.2004, 16:16 Uhr
GateKeeper



@ Pablo:

Damit kann ich ja nur alle Klassen aus einer Quelldatei einbinden. Ich möchte aber nur die erforderliche Klasse einbinden.

Außerdem möchte ich vermeiden, dass <Datei1.h> in Dateien eingebunden wird, in die ich <Datei2.h> mittels "include" einbinde - so wie im folgenden:

Datei3.h:

C++:
#include "Datei2.h" // ist "Datei1.h" jetzt nicht mit eingebunden?
#include "Datei1.h" // ist "Datei1.h" jetzt nicht einmal mehr als nötig eingebunden?



Womöglich entstehen dadurch letztendlich unüberschaubare Querbezüge, die vielleicht nicht einmal die Funktion beeinträchtigen, wohl aber Übersicht und Quelldateigrößen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
27.08.2004, 16:41 Uhr
GateKeeper



@ 0xdeadbeef:

Deine Lösung würde mich ermuntern, "Datei1.h" öfter als vielleicht nötig einzubinden (Es kann ja nichts schiefgehen) dadurch habe ich aber vielleicht viele überflüssige Zeilen in meinen Quelldateien. Außerdem muss der Präprozessor doch immer wieder prüfen, dass INCLUDED_DATEI_H nicht schon definiert ist.

Nichtsdestotrotz, wenn es keine Alternative gibt werde ich mich wohl deiner Variante bedienen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
27.08.2004, 16:52 Uhr
0xdeadbeef
Gott
(Operator)


Das mit den Include-Guards ist schon die kanonische Variante, und die Größe der Quelldatei wird dadurch ja auch nicht beeinträchtigt - lediglich der Präprozessor hat etwas mehr zu tun, aber auch das bewegt sich in keinem kritischen Bereich, solange du nicht auf nem 8088er entwickelst. Was die Querbezüge angeht,

C++:
//a.h
#ifndef INCLUDED_A_H
#define INCLUDED_A_H
#include "b.h"
struct A { B b; };
#endif

//b.h
#ifndef INCLUDED_B_H
#define INCLUDED_B_H
#include "a.h"
struct B { A a; };
#endif


geht natürlich nicht und kann auch garnicht gehen, denn wenn A B enthält und B A enthält, enthält B indirekt sich selbst. Du kannst allerdings Pointer und Referenzen benutzen, dafür reicht eine Vorwärtsdeklaration:

C++:
struct B;

struct A { B &b; A(B&); };

struct B { };

A::A(B &b) : b(b) { }


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
27.08.2004, 17:22 Uhr
Pablo
Supertux
(Operator)



Zitat von GateKeeper:
@ Pablo:

Damit kann ich ja nur alle Klassen aus einer Quelldatei einbinden. Ich möchte aber nur die erforderliche Klasse einbinden.

Außerdem möchte ich vermeiden, dass <Datei1.h> in Dateien eingebunden wird, in die ich <Datei2.h> mittels "include" einbinde - so wie im folgenden:

Datei3.h:

C++:
#include "Datei2.h" // ist "Datei1.h" jetzt nicht mit eingebunden?
#include "Datei1.h" // ist "Datei1.h" jetzt nicht einmal mehr als nötig eingebunden?



Womöglich entstehen dadurch letztendlich unüberschaubare Querbezüge, die vielleicht nicht einmal die Funktion beeinträchtigen, wohl aber Übersicht und Quelldateigrößen.


Ich seh keinen Unterschied (außer Include-Guards) zwischen beefys Lösung und meine.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 27.08.2004 um 17:22 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
27.08.2004, 20:16 Uhr
GateKeeper



@ Pablo:

Nein, du hast recht da ist sonst wirklich keiner. Eure beiden Lösungen bestätigen leider meine Befürchtungen.

@ 0xdeadbeef:

Leider ist dein Beispiel mir zu kompliziert. So verstehe ich allein den Ausdruck
C++:
A(B&)
(was macht der Operator hinter dem B?) schon mal nicht. Dein Beispiel beschreibt wohl einen Weg, wie man zwei sich selbst enthaltende Typen auf zulässige Weise deklarieren kann. Das hatte ich aber noch nicht vor (ich wüßte ad hoc auch nicht, wozu mir das nützen könnte).

Also vielen Dank bis hierhin.

Nun nämlich weiß ich wenigstens woran ich bin: Es ist offenbar nicht möglich eine einzelne Klasse aus einer anderen Quelldatei einzubinden, ohne

1. die ganze Quelldatei mit "include" einzubinden oder

2. wie bei Funktionen oder Variablen ohne Einbindung der Quelldatei durch "include" das Schlüsselwort "extern" gefolgt vom vollständigen Prototypen anzugeben.

Die kürzeste Form der Einbindung einer Klasse in eine andere Quelldatei besteht - wenn man nicht die include-funktion verwenden möchte - wohl in der Aufnahme des kompletten Prototyps der Klasse in die andere Quelldatei!

Dieser Post wurde am 27.08.2004 um 20:19 Uhr von GateKeeper editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
27.08.2004, 20:42 Uhr
Pablo
Supertux
(Operator)



C++:
struct B;



deklariert eine Struktur namens B. Eine Struktur ist wie eine Klasse.


C++:
struct A { B &b; A(B&); };



deklarier eine Struktur namens A, die eine Referenz Variable b (siehe am & Operator) vom Typ B hat, und die eine Funktion hat, die A heißt (wie ein Konstruktor), deren Argument eine Referenz auf ein B Objekt sein soll.


C++:
struct B { };



definiert die Struktur. In diesem Beispiel, ist sie leer, keine Funktionen und Variablen sind enthalten.


C++:
A::A(B &b) : b(b) { }



definition der Funktion A(B&) der Struktur A.

Wenn andere Dateien über die Klasse verfügen, reicht es, dass diese Dateien nur die Prototypen der Klassen bekmmen, und dafür sind die header Dateien und dafür ist #include da.


Zitat:

wenn man nicht die include-funktion verwenden möchte



include ist keine Funktion, sonderne in Preprozesor.


Zitat:

Die kürzeste Form der Einbindung einer Klasse in eine andere Quelldatei besteht wohl in der Aufnahme des kompletten Prototyps der Klasse in die andere Quelldatei!



Warum willst du #include nicht benutzen? Wenn du die Prototypen kopierst, könnte es sein, dass du nachher Fehler wegen Doppeldeklaraion bekommst. Siehe beefy's Beispiel mit den Guards, das ist besser so.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 27.08.2004 um 20:42 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
28.08.2004, 11:32 Uhr
GateKeeper



@ Pablo:

Deine ausführliche Erklärung ist gut. Wenn ich richtig verstehe kann man entgegen meines bisherigen Wissens also

1. einer Struktur auch Funktionen hinzufügen (hier A())
2. Strukturen über Pointer oder Referenzen auch vor deren Definition in eine andere Struktur einbinden.

Das scheint ja genauso mit Klassen möglich zu sein. folgendes Beispiel funktioniert jedenfalls.


C++:
class X;

struct A { X &b; A(X&); };

class X { };



Den Ausdruck

C++:
A::A(B &b) : b(b) { }


verstehe ich zwar noch nicht ganz (was macht der Doppelpunkt und die zweite Deklaration b(b) hinter Deklaration von A::A ?) aber der Rest ist nun viel klarer.

An der Verwendung des Präprozessorbefehls "include" stört(e) mich folgendes: Angenommen ich habe folgende Quelldatei:

Datei1.h:

C++:
Funktion1() ;
Funktion2() ;
Funktion3() ;
Funktion4() ;


(Definitionen in Datei1.cpp)

Angenommen ich möchte nach einiger Zeit die Funktionen Funktion3() und Funktion4() in eine andere Quelldatei (Datei2.h und Datei2.cpp für die Definitionen) verschieben.

Wenn ich die Funktionen nun mittels "extern" eingebunden hätte, dann könnte ich die Verschiebung durchführen, ohne etwas an den anderen Quelldateien zu ändern.

Habe ich die Funktionen aber mittels "include" eingebunden, muss ich nun in allen Quelldateien, die Funktion3() oder Funktion4() benötigen, einen neuen include-Befehl hinzufügen, nämlich

C++:
#include "Datei2.h"



In manchen Quelldateien bräuchte ich dann den noch existierenden Befehl

C++:
#include "Datei1.h"



gar nicht mehr, weil die Datei vielleicht nicht wegen der Funktionen 1 und 2 sondern nur wegen 3 oder 4 eingebunden war.

Jedenfalls müsste ich nach jeder Veränderung der Aufteilung meiner Klassen, Strukturen und Funktionen auf die einzelnen Quelldateien auch alle bezugnehmenden "include"-Anweisungen überprüfen.

Der Nachteil ist wohl, dass ich bei jeder Änderung des Prototypen auch in den bezugnehmenden Quelldateien den Prototypen ändern muss. Aber das sagt mir der Compiler/Linker dann wahrscheinlich (oder doch nicht? - ich hab es noch nicht probiert!), so dass ich es nicht selbst überprüfen muss.

Dieser Post wurde am 28.08.2004 um 11:40 Uhr von GateKeeper editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: