JGU Logo JGU Logo JGU Logo JGU Logo

Institut für Informatik

Michael Wand
David Hartmann
Sommersemester 2020DIGITAL

Blatt 06

Aufgabe 01
Einführung in die Softwareentwicklung



Aufgabe Includes

Letzte Änderung: 03. June 2020, 12:22 Uhr
8 Punkteim Detail
Ansicht:   |  


  1. Die folgenden drei Dateien kompillieren nicht.
    1. Erklären Sie wo das Problem liegt.
    2. Verändern Sie die Header so, dass das Problem nicht mehr auftritt.
      Hinweis: Include Guards (Vorlesung C08 - Modularisierung)
    3. Es gibt eine weitere Möglichkeit nur die main.cpp abzuändern, sodass das Problem nicht mehr auftauchen würde, nämlich indem man die Zeile #2, #include "B.h" aus der main.cpp entfernt. Verifizieren Sie zuerst, dass diese Änderung eine Kompillierung des ursprünglichen Codes ermöglicht.
      Wieso ist diese zweite Methode trotzdem nicht zu empfehlen?
    Codeschnipsel
    Datei A.h
    #include "<iostream>"
    #include "B.h"
    
    struct A {
        B b;
        A(B _b) : b(_b) {}
        void print() {
            std::cout << "B=";
            b.print();
        }
    };
    


    Datei B.h
    #include <iostream>
    
    struct B {
        int val;
        B(int _val) : val(_val) {}
        void print() {
            std::cout << "{val = " << val << "}";
        }
    };
    


    Datei main.cpp
    #include "A.h"
    #include "B.h"
    #include <iostream>
    
    int main() {
        B b(42);
        A a(b);
        b.print();
        std::cout << "\n";
        a.print();
        return 0;
    }
    


  2. Wir haben nun einen neuen Fall, in dem zwei Klassen die jeweils andere speichern müssten. Der Code kompilliert nicht, dieses mal erscheint jedoch eine andere Fehlermeldung.
    Erklären Sie wo das Problem liegt.
    Codeschnipsel
    Datei left.h
    #include "right.h"
    
    struct Left {
        Right right;
        Left(Right _right) : right(_right) {}
    };
    


    Datei right.h
    #include "left.h"
    
    struct Right {
        Left left;
        Right(Left _left) : left(_left) {}
    };
    


    Datei main.cpp
    #include "left.h"
    #include "right.h"
    #include <iostream>
    
    int main() {
    }
    


  3. Codebeispiel 2 hat nichts gebracht. Wir haben aber gehört, dass Forward-Declaration helfen soll. Dies sind „unausgefüllte“ Deklarationen der Structs oder Klassen, ohne weitere Details über diese mit anzugeben.

    Wir erklären in C++ so, dass eine Klasse (im folgenden Code-Schnipsel Car) später definiert wird und stellen nur sicher, dass der Compiler weiß, dass dieses Objekt existiert (wir müssen nur sicherstellen, dass die Klasse später genauer definiert wird). Der Nachteil hierbei ist, dass wir bis die Klasse genauer definiert wird, auf keine Details (Member, Speichergröße) zurückgreifen dürfen. Reine Pointer sind jedoch vollkommen okay, da der Speicher dafür stets durch size_t gegeben ist. Die Syntax dafür sieht folgendermaßen aus:
    class Car;     // forward declaration
    
    class Wheel {
        Car* car;
    };
    


    Direkt im nächsten Versuch probieren wir also Pointer aus. Dummerweise kompilliert der Code trotzdem nicht.
    Lösen Sie den Fehler mithilfe der hier erklärten Forward-Declarations im Header.
    Codeschnipsel
    Datei left.h
    #include "right.h"
    
    struct Left {
        Right *right;
        Left(Right *_right) : right(_right) {}
    };
    


    Datei right.h
    #include "left.h"
    
    struct Right {
        Left *left;
        Right(Left *_left) : left(_left) {}
    };
    


    Datei main.cpp
    #include "left.h"
    #include <iostream>
    
    int main() {
    }