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 <
010
28.08.2004, 13:37 Uhr
Pablo
Supertux
(Operator)


Soweit ich weiß, ist der Unterschied ziwschen struct und class nur der, dass die Elemente von struct alle öffentlich sind. Sonst gibt es keine Unterschiede, glaube ich.

Was

C++:
: b(b) { }



macht, ist mir nicht klar.

Was A::A macht ist folgendes:
Du fragst, was soll das :: und das A::. Das :: ist Bezeichnung für den Namensbereich, A::B heißt "benutze B vom Namensbreich/Klasse A". Das ist abstrakt, hier ein Beispiel:


C++:

/* klassen.h */

#ifndef KLASSEN_BSP
#define KLASSEN_BSP
#include <string>
#include <iostream>

class DE
{
    std::string name;
    public:
    DE(std::string); /* Konstruktor */
    void say_hello();
};

class EN
{
    std::string name;
    public:
    EN(std::string); /* Konstruktor */
    void say_hello();
};
#endif



Dass die Klassen gleich aussehen, ist hier ein Zufall. Was wichtig ist, dass beide Klassen die Funktion void say_hello() haben!


C++:
/* klassen.cpp */

#include "klassen.h"

DE::DE(std::string name)
{
    this->name = name;
}

void DE::say_hello()
{
    std::cout << "Hallo, " << this->name << "! Wie geht es dir?" << std::endl;
}

EN::EN(std::string name)
{
    this->name = name;
}

void EN::say_hello()
{
    std::cout << "Hello, " << this->name << "! How are you? " << std::endl;
}



So, in klassen.h habe ich die Klassenprototypen. Diese Header Datei hat aber keine Implementierung der Konstruktoren und der Funktionen. Sie dienen nur dazu, dass alle andere .cpp Dateien drüber wissen, welche Struktur die Klassen haben.

In klassen.cpp habe ich die Implementierung der Klassen. Guck mal, es gibt zweimal void say_hello. Woher soll der Kompiler wissen, dass es sich um die Funktion say_hello der Klasse DE bzw. EN handelt? Woher weiß der Compiler, dass void say_hello überhaupt einer Klasse gehört?

Dafür ist :: da. Mit void DE::day_hello teile ich dem Compiler mit, dass es sich um die Funktion say_hello der Klasse DE handlelt.


C++:
#include "klassen.h"

int main(int argc, char** argv)
{

    if (argc != 2)
    {
        std::cerr << "usage: " << argv[0] << " your_name" << std::endl;
        return 1;
    }

    std::string name = argv[1];

    DE deutsch(name);
    EN english(name);

    deutsch.say_hello();
    english.say_hello();

    return 0;
}



Diese 3. Datei dürfte die Antwort auf deine andere Frage. In den Header Dateien sind nur die Prototypen, die sorgen dafür, dass die Source Dateien (.cpp) wissen, welche Strukuturen zur Verfügung stehen, wie sie implementiert sind, ist es egal. Und so habe ich kompiliert:


bash:

$ g++ klassen.cpp -c



Die Datei klassen.cpp wird nur kompiliert, eine Objekt Datei wird dadurch mit dem Namen klassen.o erzeugt.


bash:

$ g++ main.cpp -c



Die Datei main.cpp wird nur kompiliert, eine Objekt Datei wird dadurch mit dem Namen main.o erzeugt.

Der Kompiler hat beide Dateien kompiliert, mit Hilfe der Header Datei klassen.h weiß der Compiler, wie die Klasse DE bzw. EN aussieht, und auch, wem die Funktionen gehört. Ich habe nur 2 .o Dateien, aber ich habe keine ausführbare Datei, d.h. ich kann noch kein Programm ausführen. D.h. aus den Objekt Dateien muss ich eine ausführbare Datei erzeugen. Dafür benutze ich den Linker. Der Linker sorgt dafür, die objekt Dateien zusammenzufügen und daraus eine ausfühbare Datei zu erzeugen.


bash:

$ g++ -o hello main.o klassen.o



g++ linkt beide Objekt Dateien und erzeugt eine ausführbare Datei (hello). Nun kann ich das Programm ausführen


bash:

rex@supertux:~/tmp/funsoft> ./hello Pablo
Hallo, Pablo! Wie geht es dir?
Hello, Pablo! How are you?


--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
29.08.2004, 12:38 Uhr
GateKeeper



@ Pablo:

Ok. Das mit der Header- und Definitionsdatei-Verwaltung habe ich jetzt glaub ich durchblickt.
Include-Guards sind eine tolle Sache. Werde ich ab jetzt sicher immer benutzen.

Eine Frage noch: Du setzt immer "std::" vor ganz normale Bezeichner. Das ist dann ja wohl eine Namespace-Angabe, die nicht unbedingt erforderlich ist. Gehört das zu guter Programmierpraxis heute? Ich sehe nämlich noch sehr viel Code, in dem das "std::" nicht angegeben ist!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
29.08.2004, 12:44 Uhr
0xdeadbeef
Gott
(Operator)


Dann benutzen die Leute entweder alte non-standard-header wie iostream.h statt iostream, oder irgendwo im Code steht ein

C++:
using namespace std;


Ich für meinen Teil behalte die namespaces recht gerne im Code, weils dadurch - wie ich finde - übersichtlicher wird. Bei zu langen namespaces wie boost::filesystem greife ich dann auf namespace-aliases zurück, z.B.

C++:
namespace fs = boost::filesystem;

//...

fs::path my_path("/");


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



Zitat von GateKeeper:
@ Pablo:

Eine Frage noch: Du setzt immer "std::" vor ganz normale Bezeichner. Das ist dann ja wohl eine Namespace-Angabe, die nicht unbedingt erforderlich ist. Gehört das zu guter Programmierpraxis heute? Ich sehe nämlich noch sehr viel Code, in dem das "std::" nicht angegeben ist!


Früher hat man #include <iostream.h> eingebunden. Nach C99 muss heute
#include <iostream> sein, wobei Objekte wie cout, cin, endl, usw. sich im Namespace std befinden. Ein guter Compiler sollte das nicht kompilieren


C++:
#include <iostream>
int main()
{
    cout << "So geht es nicht " << endl;
    return 0;
}



Mein g++ sagt dazu:


bash:

rex@supertux:~> g++ -oa a.cpp
a.cpp: In function `int main()':
a.cpp:4: error: `cout' undeclared (first use this function)
a.cpp:4: error: (Each undeclared identifier is reported only once for each
   function it appears in.)
a.cpp:4: error: `endl' undeclared (first use this function)


--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
29.08.2004, 14:36 Uhr
0xdeadbeef
Gott
(Operator)


Du meinst ISO-C++98, nicht ISO-C99.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
29.08.2004, 18:51 Uhr
Pablo
Supertux
(Operator)


ok, dann ISO-C++98. Mit C++ kenne ich mich nicht gut aus.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
29.08.2004, 22:26 Uhr
GateKeeper



Also ich habe interessehalber mal nachgeschaut, bis ich dann gähnen musste: Ursprünglich wurde aus C++ wohl 1998 eine ISO-Norm, aber seitdem sind hunderte von Änderungen und Updates erschienen. Allein 2004 wurden wohl 9 neue Artikel verfasst und ca. 20 überarbeitet, wie unter

www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html

(sehr gut zu finden über bjarne stroustrups-Homepage) zu lesen ist.

Das ist ja wie das deutsche Steuerrecht - auf jeden Fall wirkt das sehr ... kompliziert. Welchen Stellenwert gebt ihr diesen Normen in der Programmierpraxis? (Jedes Jahr mal reinschauen oder eher wirklich IMMER auf dem Laufenden sein?)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
30.08.2004, 10:07 Uhr
0xdeadbeef
Gott
(Operator)


Der Standard ist immer noch der Kram von 98. Es gibt seitdem zigtausend Vorschläge und Erweiterungen, die mehr oder weniger sinnvoll sind, aber im Grunde ist es am sinnvollsten, sich an den Standard zu halten, so weit es geht - damit bist du auf einer recht sicheren Seite, denn den Standard sollte jeder Compiler erfüllen.

Allerdings kann wohl kaum jemand den ganzen Standard auswändig, von daher sieht es in der Praxis eher so aus, dass man sich an das hält, was der eigene Compiler kann und ggf. flickt, wenn ein anderer das nicht unterstützt. Die größte Kenntnis des Standards bringt dir nichts, wenn der Compiler nachher doch die Scopes durcheinanderbringt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
30.08.2004, 13:56 Uhr
(un)wissender
Niveauwart


Mann sollte Code, der der Öffentlichkeit zugänglich gemacht werden soll immer mit mehreren Compilern kompilieren können.
Visual Studio (IDE + Compiler) macht da oft Ärger, bspw. wird nicht automatisch ein Linebreak an die Sourcen gehängt, was vielen Compilern Schwierigkeiten macht.
Also immer zum testen mit mehreren Compilern kompilieren!
--
Wer früher stirbt ist länger tot.
 
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: