Einige Fragen zu C++

  • C++

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Einige Fragen zu C++

    Hallo Leute,

    1. Benötigen Interface überhaupt eine cpp Datei? Im Prinzip stehen doch alle zu überschreibenden Methoden im Header?

    2. Hinterlegt Ihr die Header Dateien mit bei der Cpp Datei, oder in einen anderen Ordner?
    Was meinst Du mit

    ThuCommix schrieb:

    Interface
    im Zusammenhang mit c++?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Was meinst Du mit

    ThuCommix schrieb:

    Interface
    im Zusammenhang mit c++?



    Naja, eine Klasse mit virtuellen Funktionen ;)

    ​Ich hab nich viel Ahnung von Cpp aber alle Projekte die ich bisher gesehen habe hatten .cpp und .h files im selben Ordner, gleich benannt.


    Danke
    1. Natürlich reichts. Hast ja nur Prototypen. Lass dich aber vom .Net Interface denken nicht einschränken.
    2. Ich trenne es gerne, wenn es die IDE einfach zulässt ( NDK + eclipse *hust* ). Machts übersichtlicher. Und eine gute IDE lässt dich auch schnell hin und her switchen.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Interfaces sind ja Klassen mit reinen Funktionen, einem virtuellen Destruktor und optional statischen konstanten Feldern. Braucht man eher selten in C++, aber ja, ein Header reicht völlig. Ich lege Source und Header immer in den selben Ordner, kann aber jeder machen wie er will. Meistens ist ja auch Source im Header.
    Ich greife den Thread noch mal kurz auf. Ich habe folgendes Problem: Ich ich versuche im Header eine andere Klasse zu includen, leider meint er immer die Klasse (Size) sei nicht deklariert obwohl ich den Header includet habe..
    Bilder
    • Screenshot 2014-11-01 21.14.38.png

      109,24 kB, 1.366×768, 188 mal angesehen
    Schreib die Includes mal nach oben. In welchem namespace ist Size? Ausserdem Objekte nie per Value übergeben! Hier als const Size&, const string&. Sonst läuft das nämlich alles durch den Kopierkonstruktor. Kann gewollt sein, ist es aber zu 99% nicht.
    Size& wäre die Referenz, const Size& die konstante Referenz. Konstante Referenz erlaubt dir nur auch konstante Memberfunktionen zuzugreifen. Ein Zeiger ist eigentlich immer unschön/unsauber solange der Typ nicht polymorph ist, oder ein Iterator. Hast du 33000Zeichen im string und übergibst ihn als string, dann wird eine zweite Instanz erstellt, der string komplett kopiert. Deswegen const string&, oder als Referenz wenns gebraucht wird string&. Dasselbe Problem gibts beim Rückgabewert. Gibst du einen vector<double> zurück -> Kopierkonstruktor. Das drückt natürlich extrem die Performance, deswegen gibt man da eine RValue zurück. Immer schön unterscheiden ob man Zeiger (string*), Referenz (string&), konst. Referenz (const string&/string const& etc), RValue (string&& bzw. konst. const string&&) zurück/hineingibt. Hast du die Klasse Size geschrieben? Dann nenn sie am Besten size, nach Standardnotation. Ist nicht Pflicht, sieht aber schöner aus ;)
    Okay danke für die Aufklärung! Ich habe mir die Google c++ Style guides durchgelesen wo Klassen usw Groß geschrieben wurden..Kannst du mir eine Seite empfehlen in der die Konventionen aufgelistet sind?

    Ich habe mich noch ein bisschen belesen.. const x& verhindert das ich x in der Methode verändere wie es bei x& der Fall wär?

    cprogramming.com/tutorial/const_correctness.html
    Es gibt keine Style-Guidelines. Darf jeder so machen wie er will. Ich seh es aber als sinnvoll sich der Standardbibliothek anzupassen. Sollte man auch tun. Kein Codestil hat Vor- oder Nachteile, aber man sollte immer den selben benutzen, sonst wirds unübersichtlich.

    C-Quellcode

    1. cout << Size::Maximum() << "\n" << numeric_limits<int>::max() << endl;

    Das sähe ja ziemlich bescheiden aus.

    1. Klassen, Structs, Funktionen klein schreiben, kürzen und mit Unterstrich trennen
    numeric_limits<>, string, generate_n(), std::async(test_func, arg1, ref(arg2));
    Aus Size::Maximum() wird size::max().
    2. Zeiger/Referenz/RValue hinter den Typen
    type* var, type** var, void (*func) (arg0, arg1**, arg2*)
    type& var, type&& var, const type& var (n. type const&), const type&& var.
    3. Makros groß, gekürzt und mit Unterstrich getrennt.
    #define RENDER_GRAPHICS_TYPE_H, #define LOWORD(a, b)

    Das ist das Wichtigste, dass mir so einfällt. Gibt in C++ etliche Anhängsel genannt Extensions. Zeiger (*), Referenz (&), RValue (&&), Konstant (const), keine Optimierung (volatile) etc. Folglich auch ein wilder Mix aus denen: volatile const int* const num (ein volatiler konstanter Zeiger auf ein konstantes int). Bei Funktionen: int add(int, int), virtual int add(int, int), virtual int add(int, int) = 0, void __stdcall add(int, int). Sogar beim Erben: class x : y, class x : public/protected/private y, class x : public virtual y;

    const verhindert, dass man etwas modifiziert. Man erhält also etwas Konstantes. Eine konstante Referenz wäre entsprechend eine Referenz auf etwas, dass du nicht ändern kannst. Mach mal folgenden Test:

    C-Quellcode

    1. template <typename member>
    2. class instance_counter
    3. {
    4. public:
    5. instance_counter(const member& mem) : m(mem) {cout << "Member constructed" << endl;}
    6. ~instance_counter() {cout << "Member destructed" << endl;}
    7. instance_counter(const instance_counter& ic) : m(ic.m) {cout << "Member copied" << endl;}
    8. instance_counter(const instance_counter&& ic) : m(move(ic.m)) {cout << "Member moved" << endl;}
    9. member get_copy() const {return m;}
    10. private:
    11. member m;
    12. };
    13. template <typename arg0>
    14. void test_copy(arg0)
    15. {
    16. cout << typeid(arg0).name() << "\t" << sizeof(arg0) << endl;
    17. }
    18. template <typename arg0>
    19. void test_const_ref(const arg0&)
    20. {
    21. cout << typeid(arg0).name() << "\t" << sizeof(arg0) << endl;
    22. }
    23. int main(int argc, char* argv[])
    24. {
    25. instance_counter<string> ic("Hallo, ich bin ein Text");
    26. test_copy(ic); // bzw. test_const_ref(ic);
    27. return EXIT_SUCCESS;
    28. }

    Bei test_copy gibt es zwei Instanzen á 28 Bytes, bei test_const_ref nur eine.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gonger96“ ()

    Okay verstehe. Also wenn ich z.B den Title von etwas zurückgeben möchte sieht das ungefähr so aus:

    C-Quellcode

    1. const string& get_name()


    Const weil, der User darfs nicht ändern, und die Referenz damit nicht der String kopiert werden muss?
    Als Rückgabewert ist das nicht schön, geht dann auch nur wenn die Referenz bestehen bleibt. Hier sollte man entweder eine Kopie zurückgeben (was bei einem Title sinnvoll wäre) oder eine RValue. Da der Compiler aber relativ intelligent ist, wird es so oder so gemoved. Die Funktion sollte allerdings konstant sein, damit darauf zugreifen kannst, wenn das Objekt per const& übergeben wird. Also dann string get_name() const.

    @Counterbug
    Nimm es so wie es heißt: Eine Referenz ist eine Referenz eines Typen, ein Zeiger ist ein Zeiger auf eine Addresse im Speicher (nicht immer Zeiger auf einen Typen s. void*). Folglich verbraucht ein Zeiger Speicher, eine Referenz nicht. Zeiger kannst du manipulieren und zuweisen, Referenzen nicht. Es gibt Zeiger auf Zeiger aber nur eine Referenz. Zeiger können 0 sein, Referenzen niemals. Einen Zeiger muss man auch dereferenzieren. Zeiger kann man als Array nehmen, Referenzen nicht. Referenzen können temporäre Objekte beinhalten, Zeiger nicht. Deswegen nimmt man die const& und nicht den const*.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gonger96“ ()

    Was du machen kannst, ist ein Kommentar über die Funktion schreiben. IntelliSense zeigt den sogar an.

    C-Quellcode

    1. class xy
    2. {
    3. public:
    4. // Z's the xy instance
    5. void z();
    6. };

    Macht aber eigentlich keiner. Höchstens als Hilfe, wenn der Name der Funktion nicht ganz eindeutig ist. Doku kannst du am Besten extern machen. Online oder in einer PDF, da kann man dann auch schön Beispiele reinpacken und etwas detaillierter beschreiben.