Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » headerfiles , #include, Verständnisprobleme

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
20.08.2008, 14:59 Uhr
MettMax



Hallo,

Ich arbeite mich momentan in C++ ein. Ich hab seit ca. 5 Jahren mit Delphi und vorallem Java zu tun gehabt. Also ein Grundverständnis für das was ich tue sollte da sein.

Ich bin momentan dabei mir das Prinzip von OOP in C++ näherzubringen.
Ich habe dazu ein ganz simples Beispiel.

incl.cpp:

C++:
    
class Dog
    {
    private:
      int age;

    public:
      void setAge(int newAge) { age=newAge; printf("123"); }
      int getAge() { return age; }
    };

    int main()
    {
      Dog bello;
      Dog waldi;

      bello.setAge(4);
      waldi.setAge(3);
    }


Ich weiß das es schöner wäre die Funktionen außerhalb mit Klassenname:: zu definieren. Aber mein Problem ist ein ganz anderes.
Ich habe noch eine Datei und zwar die main.cpp.
Ich würde gerne aus der main.cpp zwei Objekte des typs Dog definieren.
Also:

main.cpp:

C++:
#include <iostream>
#include <incl.h> --> ?? macht man das so?

[...]
      Dog bello;
      Dog waldi;

      bello.setAge(4);
      waldi.setAge(3);
[...]





incl.cpp:

C++:
    
class Dog
    {
    private:
      int age;

    public:
      void setAge(int newAge) { age=newAge; printf("123"); }
      int getAge() { return age; }
    };


Dazu brauche ich aber einen incl.h file. Und da verstehe ich nicht ganz warum ich sowas brauche.
Ich hab hier auch schon mehrere Tutorials gelesen, aber die gehen alle nicht so genau bis garnicht darauf ein. Ich muss die incl.cpp jetzt wahrscheinlich einfach als incl.h speichern und kompilieren(??).... aber wieso?? Wozu genau dient das,bzw kann/sollte ich die cpp Datei nicht einfach irgendwie includen.

Könnt Ihr mir das erklären??
Danke
Max
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.08.2008, 16:16 Uhr
xXx
Devil


Hmm ... Ja du musst sie als solches Speichern.

dog.hpp

C++:
#pragma once

#include <iostream> // std::cout

class Dog
{
    unsigned char m_age;

public:
    Dog() // {c-tor} => Dog is born
        : m_age(0) // Initialisierungsliste
    {}

public:
    void add_new_year() { std::cout << ++m_age << " years old!\n"; }
    const unsigned char get_age() const { return m_age; }
};
also bitte auf die beiden "const" achten, sowie auf den Konstruktor, damit m_age einen Wert hat, auch wenn setAge mal nicht aufgerufen wird Dann unsigned, oder hast du schon nen Hund mit -20 Jahren Lebensalter gesehen? Nein ... char statt int, denn du wirst auch keinen Hund sehen der mehr als höchstens 20 ist. Von der Logik her, kann nen Hund nicht einfach das alter gesetzt bekommen und von d.h. kann höchstens ein Jahr vergehen ...

Dieser Post wurde am 20.08.2008 um 16:16 Uhr von xXx editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.08.2008, 16:28 Uhr
0xdeadbeef
Gott
(Operator)


Zunächst mal lege ich dir die Lektüre von www.eng.hawaii.edu/Tutor/Make/ nahe. Es handelt sich dabei um ein make-Tutorial, wobei der make-bezogene Teil für dich vorerst nicht weiter wichtig ist. Am Anfang beschreibt es allerdings, wie die Kompilation von C-Programmen funktioniert, und da der Mechanismus in C++ der selbe ist, sollte das dem Verständnis weiterhelfen.

Vom technischen her, #include macht nichts anderes als Textersetzung, wie alle Präprozessordirektiven. Das heißt,

C++:
#include "incl.h"


nimmt den Inhalt von incl.h und fügt ihn da ein, wo diese Direktive steht. Erst nachdem der Präprozessor durch ist, geht das Ergebnis an den eigentlichen Compiler. Konkret bedeutet das, dass der Compiler gar nicht mehr sieht (oder sich zumindest nicht mehr dafür interessiert), aus welchen Dateien der Kram ursprünglich kam.

Im Folgenden gehe ich davon aus, dass du den obrigen Link bereits gelesen hast.

Der Grund dafür, dass man C++-Code in Header- und Source-Dateien aufteilt, liegt dann beim Linker. Header-Dateien enthalten Deklarationen, aber keine Implementierung (Templates lassen wir für den Moment beiseite), Source-Dateien enthalten die Implementierung der im Header deklarierten Dinge. Wenn man Source-Dateien einbände, tauchte der selbe Code - beziehungsweise gleich benannter Code - in mehreren Objekten auf, und der Linker wüsste nicht, welchen er denn jetzt benutzen soll.

Konkret für deinen Fall bedeutet das, trenn die Klasse auf, z.B. in

C++:
// dog.hpp
#ifndef INCLUDED_DOG_HPP
#define INCLUDED_DOG_HPP

class dog {
public:
  void age(int);
  int age() const;

private:
  int age_;
};

#endif




C++:
// dog.cpp
#include "dog.hpp"

void dog::age(int age) { age_ = age; }
int dog::age() const { return age_; }




C++:
// main.cpp
#include "dog.hpp"

#include <iostream>

int main() {
  dog d;

  dog.age(4);
  std::cout << dog.age() << std::endl;
}



Nachtrag: Im Übrigen muss main im globalen namespace liegen, sonst ist sie lediglich eine merkwürdig benannte Methode

Nachtrag 2: Gewöhn dir bloß nicht diesen #pragma once-Unsinn an, einige Compiler hauen dir das um die Ohren.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 20.08.2008 um 16:30 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
20.08.2008, 19:35 Uhr
Lensflare




Zitat von xXx:

char statt int, denn du wirst auch keinen Hund sehen der mehr als höchstens 20 ist.


Ich hab schon mehrmals gelesen, dass es besser ist, eben doch int zu verwenden,
weil int von der CPU schneller verarbeitet wird und genauso viel Speicher belegt wie kleinere Typen.

z.B. hier:
http://newmaxim.ne.funpic.de/create_page.php?file=leistungstipps.html&dir=artikel/cpp
(4. 32-Bit Variablen verwenden.)

Und in C/C++ Libs, in die ich mal einen Blick geworfen habe (OpenGL, Allegro) verwendet man auch fast ausschließlich int. Sogar da, wo man auch bool nehmen könnte.

Kann man es vielleicht damit begründen, dass es davon abhängig ist, ob man auf Leistung oder auf Fehlervermeidung Wert legt?
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
20.08.2008, 20:56 Uhr
~Hi
Gast


Hallo,

#pragma once kann man meistens ruhig verwenden. "einige Compiler hauen dir das um die Ohren." ...einige Compiler sehen ziemlich alt aus...

VC++ genauso wie GCC und andere Compiler unterstützen es, also wo ist das Problem? Alles Sachen um die man sich keine Gedanken machen muss.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
20.08.2008, 22:44 Uhr
0xdeadbeef
Gott
(Operator)


Ganz grundsätzlich ist es doch so - pragma once bietet keinen Vorteil gegenüber include-Guards, und ist nicht standardisiert. Das heißt nicht nur, dass nicht jeder Compiler es unterstützen muss, sondern auch ganz unterschiedliche Sachen daraus machen kann - ich erinnere mich da z.B. an Probleme mit sym- und hardlinks im gcc, vor, zugegeben, recht langer Zeit.

Pragmas sind stumpf und ergreifend nicht portabel. Ihr Anwendungsbereich liegt nicht in der Codelogik, sondern im Compilerspezifischen - wie z.B. #pragma GCC visibility - wo Portabilität von vornherein nicht gefragt ist.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
20.08.2008, 22:47 Uhr
~Jo
Gast


Abend,

Ich bin ebenfalls der Meinung, dass man #pragma once heutzutage problemlos benutzen kann.

Falls da ein Compiler wirklich meckert, sollte man diesen vielleicht lieber updaten oder auch auf einen zeitgemäßen umsteigen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
20.08.2008, 22:54 Uhr
0xdeadbeef
Gott
(Operator)


Jungs, nirgendwo steht festgeschrieben, was #pragma once macht, das ist das Problem! Der Compiler wird über ein Pragma nicht meckern, unbekannte pragmas werden ignoriert. Aber ob er macht, was du willst, ist eine ganz andere Frage.

Ihr lagert hier die Bedeutung des Codes vom Code zum Dateisystem des umgebenden Betriebssystems aus. Wer in seiner kleinen Windowswelt bleibt, den mag das nicht groß stören - da gibt's ja nur Dateien - aber unter richtigen Betriebssystemen und auf embedded-Geräten kann das schon mal ganz anders aussehen. Oh, die Compilerbauer werden mit aller Wahrscheinlichkeit versuchen, das Verhalten ähnlich zu gestalten, aber ob das z.B. im Hurd gelingt, ist eine ganz andere Frage.

Eine solche Angewohnheit wartet nur darauf, in die Hose zu gehen, und es ist ein völlig unnötiges Risiko - es bietet gegenüber standardkonformen Maßnahmen keinerlei Vorteil.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
20.08.2008, 23:18 Uhr
xXx
Devil


Jo, hab es eigtl. immer so gehalten, beides zu nutzen, also #pragma once und normalen Inc.-Guard ... war jetzt nur etwas Tipp-Faul.

Und doch, #pragma once sollte eigtl. Zeitgewinne beim Linken bzw. beim Compilieren, bringen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
21.08.2008, 00:23 Uhr
0xdeadbeef
Gott
(Operator)


Beim Linken nicht, da sind die Header schon lange durch. Beim Kompilieren...denkbar, ich weiß aber zumindest vom gcc, dass der das wegoptimiert ( http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html ).
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
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: