Undefiniertes class C2079



  • Ich verstehe nicht, warum die definition von class Silo aus der Silo.cpp die ja über Classen.h eigentlich in der main.cpp includiert sein sollte trotzdem nicht da ist. MS Visual Studio 2015 findet die Definition per rechtklick aber der Compiler anscheinend nicht also helft mir doch bitte mal auf die Sprünge:

    main.cpp

    #include"Classen.h"
    std::vector<Silo> silos;
    
    int main()
    {
    	std::locale::global(std::locale("German"));
    	int wahl{ 0 };
    
    	while(wahl !=9){
    		std::cout << "Haupmenü:\n\n"
    			<< "<1> neu\n"
    			<< "<2> ändern\n"
    			<< "<9> beenden\n";
    		std::cin>>wahl;
    		switch (wahl) {
    		case 1: {std::locale::global(std::locale("German"));
    			int wahl{ 0 };
    			std::cout << "Neu:\n\n"
    				<< "<1> Silo\n"
    				<< "<2> hier ist noch nichts\n"
    				<< "<3> hier auch nicht\n";
    			std::cin >> wahl;
    			switch (wahl)
    			{
    			case 1: {
    				int g = sizeof(silos);
    				Silo tmpo; // C2079 tmpo verwendet undefiniertes class "Silo"
    				tmpo.neu_Silo(); // C2228 Links von ".neu_Silo" müssen sich in einer Klasse/... befinden
    				silos.push_back(tmpo); // C2664 konvertierung von int in Silo&& nicht möglich
    
    				break; }
    			case 2: {
    
    				break; }
    			}}
    		case 2: {andern_menu();
    			break; }
    		case 9: return 0;
    		}
    	}
    
    	return 0;
    }
    

    classen.h

    #pragma once
    #include<locale>
    #include<iostream>
    #include<string>
    #include<vector>
    #ifndef CLASSEN_H
    #define CLASSEN_H
    
    class Silo; // das ist doch eine deklaration
    enum class Getreide : int {Leer, Körnermais, Hächselmais, Raps, Weizen, Gerste, Roggen, Tritkale, Mist, Gülle};
    void andern_menu();
    
    #endif
    

    silo.cpp

    #include"Classen.h"
    
    class Silo
    {
    public:
    
    	void neu_Silo();
    	void art_andern();
    
    private:
    	unsigned int silo_nr{ 0 };
    	Getreide art{ Getreide::Leer };
    	unsigned int max_vol{ 1000 };
    	unsigned int vol{ 0 };
    };
    
    void Silo::neu_Silo() {
    	std::locale::global(std::locale("German"));
    	std::cout << "Die Silonumer wird automatisch festgelegt:" << silo_nr << std::endl;
    	std::cout << "Geben sie bitte das Maximale Volumen ein(Kubikmeter)\n";
    	std::cin >> max_vol;
    	std::cout << "das Silo ist standartmäßig leer.\n";
    	art_andern();
    }
    
    void Silo::art_andern() {
    	std::locale::global(std::locale("German"));
    	int wahl{ 0 };
    	std::cout << "Wählen sie eine Getreideart\n"
    		<< "<1> Körnermeis\n"
    		<< "<2> Hächselmais\n"
    //		noch 7 weitere
    ;
    	do {
    		std::cin >> wahl;
    		switch (wahl) {
    		case 1: { art = Getreide::Körnermais;
    			break; }
                    // hier noch case 2 - case 9
    		default: std::cout << "Falsche Eingabe\n";
    		}
    	} while ((wahl >= 1) && (wahl <= 9));
    
    }// hier ist die klasse doch vollständig definiert und nicht mehr unvollständig oder?
    

    schon mal danke 🙂



  • Der compiler hat recht! Du hast in deinem Header nur eine Vorwärtsdeklaration. Du kannst nur die Implementierung der Funktionen auslagern, die Klassendefinition musss in den Header.



  • Also es funktioniert, aber nur zum Verständnis muss die Definition einer klasse immer in der Headerdatei passieren? ich habe mir nämlich ein Buch gekauft und dort wird erst in der .cpp Datei definiert...



  • poster8 schrieb:

    Also es funktioniert, aber nur zum Verständnis muss die Definition einer klasse immer in der Headerdatei passieren? ich habe mir nämlich ein Buch gekauft und dort wird erst in der .cpp Datei definiert...

    Nein, man kann eine Klasse auch der .cpp-Datei definieren, dann kann man sie allerdings
    auch nur dort verwenden, bzw. außerhalb kann man höchstens Pointer auf die Klasse
    herumreichen, nicht jedoch auf ihre Member zugreifen (in Ausnahmefällen ist das sogar so gewollt - Stichwort "opaque pointer").

    Deine main.cpp verwendet jedoch die Klasse. Beispielsweise wird mit Silo tmpo; eine Instanz von Silo erzeugt.
    Dafür muss mindestens die Größe der Klasse bekannt sein und auf den Default-Konstruktor zugegriffen werden. Daher gehört die Definition in diesem Fall in den Header.

    Gruss,
    Finnegan



  • poster8 schrieb:

    Also es funktioniert, aber nur zum Verständnis muss die Definition einer klasse immer in der Headerdatei passieren? ich habe mir nämlich ein Buch gekauft und dort wird erst in der .cpp Datei definiert...

    Die Zeilen 3-15 aus Deiner *.cpp musst Du in die *.h verschieben. Was anderes wird Dein Buch auch nicht schreiben. Evtl. verhaut der Autor aber im Text den Unterschied zwischen Deklaration u. Definition.



  • Schau dir am besten noch einmal an, wie das in C++ mit den Modulen läuft. Hier ist auch eine andere Beschreibung zum Thema: http://www.willemer.de/informatik/cpp/aufteil.htm


Anmelden zum Antworten