Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Verständnisfrage zu Headerdatei u. Klassen

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 <
000
08.09.2007, 15:01 Uhr
mavedriver



Hallo alle zusammen,

bin gerade dabei mir C++ beizubringen und hab da ma zwei Frage zum Umgang mit Headerdatei und Klassen. Zunächst die Headerdatei:

In den Beispielcode zur Verwendung von Headerdatei ich immer auf folgen drei Ausdrück gestoßen:

- #ifndef _HTIER_H
- #define _HTIER_H
- #endif

Wozu brauche ich diese Ausdrücke, dass ganze Programm funktioniert ja auch ohne diese.

Beim Umgang mit Klassen habe ich das bis jetzt so gelernt, dass man bevor man eine Methode bzw einen Konstruktor definieren kann, diesen zunächst deklarieren muss. Jetzt bin ich in einem Beispielprogramm darauf gestoßen das weder Konstruktor noch Methoden deklariert, sonder direkt definiert wurden. Bedeutet das jetzt, dass man sich die Deklaration von Methoden u. Konstruktoren beim Umgang mit Klassen sparren kann oder liegt es daran, dass es sich dabei um so genannte inline Methoden handelt.

Hier der Quellcode

C++:
// htier.h

#include <iostream>
#include <cstring>
#ifndef _HTIER_H
#define  _HTIER_H
using namespace std;

class Haustier
{
    private:
    // Eigenschaften der Klasse Haustier
    char sorte[30];
    char rasse[30];
    char name[25];

    public:
    // Konstruktoren
    // Default - Konstruktoren
    
    Haustier()
    {
        strncpy( sorte, "?", sizeof("?"));
        strncpy( rasse, "?", sizeof("?"));
        strncpy( name, "?", sizeof("?"));
    }
    Haustier(const char* s, const char* r, const char* *n)
    {
        strncpy(sorte, s, sizeof(sorte)-1);
        strncpy(rasse, r, sizeof(rasse)-1);
        strncpy(name, n, sizeof(name)-1);
    }
    
    // Dekonstruktor
    ~Haustier(){ }
    
    // Fähigkeiten (Methoden) der Klasse Haustier
    // Hier nur auf Zugrifsmethoden beschränkt
    const char* get_sorte() const { return sorte; }
    const char* get_rasse() const { return rasse; }
    const char* get_name() const { return name; }

    void set_sorte(const char* s)
    {
        strncpy(sorte, s, sizeof(sorte)-1);
    }
    void set_rasse(const char* r)
    {
        strncpy(rasse, r, sizeof(rasse)-1);
    }
    void set_name(const char* n)
    {
        strncpy(name, n, sizeof(name)-1);
    }
    
};

#endif


Vielen Dank schon mal in Vorraus für eure Antworten

mfg mavedriver


Bearbeitung von 0xdeadbeef:

cpp-tags eingefügt. Nächstes mal selbst machen.


Dieser Post wurde am 08.09.2007 um 16:02 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.09.2007, 16:08 Uhr
xXx
Devil



C++:
#ifndef _HTIER_H
#define _HTIER_H
// ...
#endif // _HTIER_H
braucht man garnicht. Die gehörem dem Compiler(Die Namen mit _ davor) ... wenn se korrekt wären, sollten es Include-Guards sein.

C++:
#if !defined(TIER_H__INCLUDED)
#define TIER_H__INCLUDED

// #if (_MSC_VER >= 1300)
// #pragma once
// #endif // (_MSC_VER >= 1300)

class Tier
{
};

#endif // TIER_H__INCLUDED
...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.09.2007, 16:09 Uhr
0xdeadbeef
Gott
(Operator)


Es handelt sich dabei um include guards.

Es ist wichtig zu verstehen, dass der Präprozessor im Grunde nichts anderes als Textersetzung macht. #include "foo.h" veranlasst den Präprozessor dazu, die Direktive durch den Inhalt von foo.h zu ersetzen, Buchstabe für Buchstabe. Das bedeutet, wenn du die Include guards weglässt, und drei Header a.h, b.h und c.h hast, von denen b.h und c.h beide a.h includen, und dann in einer Sourcedatei sowohl b.h als auch c.h includest, übersetzt sich das durch den Präprozessor zu

C++:
// Inhalt von a.h
// Inhalt von b.h
// Inhalt von a.h, zum zweiten mal
// Inhalt von c.h


...und das fliegt dir fast immer um die Ohren. Mit Includeguards dagegen ist das quasi

C++:
#ifndef INCLUDED_B_H
#define INCLUDED_B_H
#ifndef INCLUDED_A_H
#define INCLUDED_A_H
// Inhalt von a.h
#endif
// Inhalt von b.h
#endif
#ifndef INCLUDED_C_H
#define INCLUDED_C_H
#ifndef INCLUDED_A_H // und das hier ist beim zweiten mal falsch
#define INCLUDED_A_H
// Inhalt von a.h
#endif
// Inhalt von c.h
#endif


Da INCLUDED_A_H beim zweiten mal definiert ist, wird daraus dann

C++:
// Inhalt von a.h
// Inhalt von b.h
// Inhalt von c.h


...und damit gibts dann auch keine Probleme.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 08.09.2007 um 16:09 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
08.09.2007, 16:37 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


der ms-compiler hat für den zweck auch das "#pragma once" erfunden (ok gut, glaub der gcc akzeptierts auch)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.09.2007, 12:03 Uhr
Kest
saint


Hi!


Zitat von mavedriver:
Beim Umgang mit Klassen habe ich das bis jetzt so gelernt, dass man bevor man eine Methode bzw einen Konstruktor definieren kann, diesen zunächst deklarieren muss.

Das stimmt nicht: muss man nicht.
Das bedeutet, dass die jeweiligen Elementfunktionen zu Inline-Elementfunktionen werden. Ob das nun aber übersichtlicher wäre, bleibt dahingestellt.

Und mit einfachen Worten dienen die Include-Wächter dafür, um den Inhalt der Datei zwischen >#ifndef< und >#endif< nicht einzufügen, wenn >_HTIER_H< bereits definiert ist.
--
Wenn man einen Hufschlag hört, sollte man >Pferd< denken und nicht >Zebra<.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.09.2007, 12:23 Uhr
xXx
Devil



C++:
#if !defined(PET_H__INCLUDED)
#define PET_H__INCLUDED

/* using namespace std;  // niemals im Header (!!!) */

#if (_MSC_VER >= 1300) // Nur Mirosoft Visual C++ (Version > 1300) wird #pragma once alse nutzen.
#pragma once
#endif // (_MSC_VER)

class Pet : public Animal
{
    std::string m_name;

public:
    Pet(const std::string& kind = "?", const std::string& name = "?", const std::string& race = "?") : Animal(kind, race) : m_name(name)
    {}    

public:
    std::string const& get_name() const { return m_name; }
    void set_name(const std::string& name) { m_name = name; }
};

#endif // PET_H__INCLUDED
...

C++:
#if !defined(ANIMAL_H__INCLUDED)
#define ANIMAL_H__INCLUDED

#if (_MSC_VER >= 1300)
#pragma once
#endif // (_MSC_VER)

class Animal
{
    std::string m_kind;
    std::string m_race;

public:
    Animal(const std::string& kind = "?", const std::string& race = "?") : m_kind(kind), m_race(race) {}    

public:
    std::string const& get_kind() const { return m_kind; }
    void set_kind(const std::string& kind) { m_kind = kind; }
    std::string const& get_race() const { return m_race; }
    void set_race(const std::string& race) { m_race = race; }
};

#endif // ANIMAL_H__INCLUDED]
...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ 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: