Du bist nicht angemeldet.

Werbeanzeige

1

06.02.2019, 23:01

Namespace nicht gefunden

Hallo,

ich habe ein Problem mit namespaces.

main.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#pragma once

#include <fstream>
#include <iostream>

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

#include "config/config.h"
#include "game/game.h"


config.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#pragma once

#include "..\main.h"

namespace cconfig
{
        class config
    {
        private:
            struct config_data {
                bool fullscreen = false;
                int  window_width = 800;
                int  window_height = 600;
            };

            
        public:

            config();
            ~config();
            void    read();
            void    write();

            config_data configuration;

    };
}


game.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once

#include "..\main.h"


namespace ggame
{
    class game
    {
        private:
            sf::VideoMode *videomode;
            sf::RenderWindow *renderwindow;
        public:
            cconfig::config *configuration;    << hier meckert der compiler Fehler  C2653   "cconfig": Keine Klasse oder Namespace

            game(cconfig::config &config);
            ~game();
            void run();
    };

}



mfg

sIR_pAPILEIN

dot

Supermoderator

Beiträge: 9 850

Wohnort: Graz

  • Private Nachricht senden

2

07.02.2019, 01:48

Was du hier hast ist ein klassischer Fall eines zirkulären #include. Nehmen wir an du hast z.B. ein .cpp File welches

C-/C++-Quelltext

1
#include "config.h"

macht.

Wir includen also "config.h". In "config.h" steht zunächst ein #pragma once. Der Compiler merkt sich an dieser Stelle, dass "config.h" bereits inkludiert wurde. Dann wird in "config.h", bevor noch irgendwas anderes passiert, "main.h" inkludiert. "main.h" inkludiert wiederum "config.h". Der Compiler schaut nach, ob "config.h" schon inkludiert wurde und merkt, dass es schon inkludiert wurde. Daher wird der #include "config.h" an dieser Stelle übersprungen. Direkt danach inkludiert "main.h" den Header "game.h", welcher wiederum "main.h" inkludiert. "main.h" hatte ebenfalls ein #pragma once und wurde an dieser Stelle schon inkludiert, daher wird der #include "..\main.h" übersprungen. Nach dem übersprungenen #include kommt direkt die Definition des Namespace ggame und der Klasse game. Bachte, dass wir auf diesem Weg an der Definition der Klasse game angelangt sind, bevor der Hauptteil von config.h durchlaufen wurde (weil config.h vor der Definition der Klasse config erstmal main.h included, welches wiederum game.h included, welches zwar indirekt config.h included, aber weil wir an dieser Stelle aus config.h selbst kommen, wird der include wegen #pragma once übersprungen). Wenn wir dann also zur Zeile

C-/C++-Quelltext

1
cconfig::config *configuration;

kommen, ist nicht bekannt, was cconfig::config sein sollte.

Die Lösung des Problems: Inkludiere immer nur was du wirklich brauchst. In deiner Definition von game musst du die Definition von config z.B. (noch) nicht kennen, weil du dort nur einen Member deklarierst, der nur ein Pointer auf eine config ist. In diesem Fall reicht eine Forward-Declaration von config aus:

C-/C++-Quelltext

1
namespace cconfig { class config; }

statt dem #include der vollständigen Definition…

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (07.02.2019, 01:53)


BlueCobold

Community-Fossil

Beiträge: 10 890

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

07.02.2019, 06:24

Statt einer Forward-Deklaration kann man natürlich auch von vornherein versuchen zu vermeiden, dass die eigenen Datentypen gegenseitig voneinander abhängen. Das ist auch logisch eigentlich ziemlicher Mist. Ein System sollte auf einem anderen aufbauen und nicht alle aufeinander gleichzeitig. In deinem Fall hier gibt es noch keine echte zyklische Abhängigkeit, nur einen unnötigen zyklischen Include, weil du überall "main.h" inkludierst, um es dir "einfach" zu machen. Tu sowas nicht. "game.h" sollte einfach nur "config.h" inkludieren und fertig. Schmeiß "main.h" einfach weg. Inkludiere überall explizit das, was du wirklich brauchst. Nicht jeder deiner Header braucht alle anderen. Das reduziert dann außerdem deine Compile-Zeit.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »BlueCobold« (07.02.2019, 06:31)


4

07.02.2019, 08:36

Die Vorwärtsdeklaration geht übrigens auch einfacher mit

C-/C++-Quelltext

1
class cconfig::config

(C++17 brauchts)

5

08.02.2019, 18:30

habs geändert, jetzt geht es (VS17 Community)

mfg

sIR_pAPILEIN

Werbeanzeige