Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Compiler- oder Codefehler?

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
31.07.2014, 20:07 Uhr
A13XIS



Hinweis: Ich Komme quasi direkt von "Team Java" und es ist echt schwer sich an die Gegebenheiten von cpp zu gewöhnen. Wundert euch also bitte nicht, wenn die folgende Frage ein echt blöder Fehler ist.


Hallo liebe Kollegen,
Ich versuche mich ,nach einem Recht langen Anlauf ,an einem SDL-programm.
Um es möglichst auf allen OS verfügbar zu machen nutze ich den MinGW G++ Compiler
(IDE ist Eclipse CDT).
Nun habe ich das Problem, dass in einem Header (Starter.h) Eine Klasse (GraphMan) vom Compiler nicht erkannt wird, obwohl Eclipse kein Problem erkennt.


C++:
     //Starter.h
          
     #pragma once
     #ifndef STARTER_H_
     #define STARTER_H_
     #include "GraphMan.h"
     #include "AudioMan.h"
     #include "InputMan.h"
     #include <iostream>
     using namespace man;
     class Starter {
        public:
         Starter();
         ~Starter();
         void gameLoop();
         void die(const char *);
         SDL_Event * ev;
        private:
           GraphMan graphics;//<--GraphMan does not name a type
           bool quit;
    };
    #endif /* STARTER_H_ */



C++:
#pragma once
#ifndef GRAPHMAN_H_
#define GRAPHMAN_H_
#include "Starter.h"
#include "SDL2/SDL.h"
#include "SDL2/SDL_image.h"
#include "SDLMan.h"
#include <vector>
#include <string>

class Starter;
struct Graphic{
    //Variablen und Konstruktor von Grafik
};
struct Sprite{
    //Variablen und Konstruktor von Sprite
};
namespace man {
class GraphMan {
public:
    GraphMan(Starter * starter);
    virtual ~GraphMan();
    void paint();
    void addGraphic(SDL_Texture * text,std::string name, SDL_Rect*pos, SDL_Rect*crop);
    void addSprite(SDL_Texture* text,std::string name,int frame,int tframes, SDL_Rect*pos, SDL_Rect*crop);
private:
    Starter*starter;
    SDL_Window * wind;
    SDL_Renderer * rend;
    std::vector<Graphic> graphVect;
    std::vector<Sprite> spriteVect;
};
} /* namespace man */
#endif /* GRAPHMAN_H_ */



an dieser Stelle sei gesagt, dass bei einem erneuten Buildversuch diese Meldung verschwindet und in der cpp-Datei dieses Objekts (starter.cpp) eine neue Auftaucht die da wirklich nichts zu suchen.


C++:
//Starter.cpp

#include "Starter.h"
Starter::Starter(){//<--no matching function for call to 'man::GraphMan::GraphMan()'

    std::cout<<"starter"<<std::endl;
    quit=false;
    ev=new SDL_Event();
    graphics = GraphMan(this);
    gameLoop();
}

Starter::~Starter() {
    delete ev;
    man::SDLMan::quit();
}



Gebe es diese "Sondermeldung" nicht wär ich mir sicher, dass ich einfach nur zu doof bin, die Objekte miteinander zu verbinden.
So ist meine Frage aber "Compiler- oder Codefehler" (und wie kann man ihn lösen)
--
Java "Programmieren"(also in Anführungszeichen). Ernsthaft?
Mit Java lässt sich viel besser arbeiten, als mit jeder anderen Sprache!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
01.08.2014, 09:29 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,

deine Initialisierung ist falsch:


C++:
Starter::Starter()
// hier an dieser Stelle legt er "graphics" in der Art "graphics = GraphMan()" an
{

    std::cout<<"starter"<<std::endl;
    quit=false;
    ev=new SDL_Event();
    graphics = GraphMan(this);
    gameLoop();
}



richtig:


C++:
Starter::Starter() : graphics(this)
{

    std::cout<<"starter"<<std::endl;
    quit=false;
    ev=new SDL_Event();
    gameLoop();
}


--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
01.08.2014, 11:37 Uhr
A13XIS



Also nein Bitte!. Es lag garantiert nicht an mir. Der Kompiler wars! (Sarkasmus )

Es hat aber wirklich geklappt. Faszinierend...
Kannst du mit bitte sagen warum es so initialisiert weden muss? Mein cpp-Buch ist zu Phätt um sowas zu finden, selbst mit Register.


[EDIT]okay doch nicht. (Erst bauen und DANN Posten, was?) Das erste Problem

Zitat:


C++:
     //Starter.h
          
     #pragma once
     #ifndef STARTER_H_
     #define STARTER_H_
     #include "GraphMan.h"
     #include "AudioMan.h"
     #include "InputMan.h"
     #include <iostream>
     using namespace man;
     class Starter {
        public:
         Starter();
         ~Starter();
         void gameLoop();
         void die(const char *);
         SDL_Event * ev;
        private:
           GraphMan graphics;//<--GraphMan does not name a type
           bool quit;
    };
    #endif /* STARTER_H_ */




ist geblieben.
Wäre schön, wen du (oder sonst jemand) das auch noch lösen könnte.
Mein cpp-Buch ist nämlich zu Phätt um die Lösung solcher Unwissenheitsfehler zu finden.
Selbst mit Register.

Ich sag schonmal !
--
Java "Programmieren"(also in Anführungszeichen). Ernsthaft?
Mit Java lässt sich viel besser arbeiten, als mit jeder anderen Sprache!

Dieser Post wurde am 01.08.2014 um 12:05 Uhr von A13XIS editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
01.08.2014, 14:28 Uhr
A13XIS



Ich habe es jedenfalls mit der Vordeklaration versucht

C++:
using namespace man;
class GraphMan;//<--'GraphMan' in namespace 'man' does not name a type
class Starter {
public:
  Starter();
    ~Starter();
    void gameLoop();
    void die(const char *);
    SDL_Event * ev;
private:
    GraphMan * graphics;//<--'GraphMan' in namespace 'man' does not name a type

    bool quit;
};



Aber auch das scheint nicht zu funktionieren.
--
Java "Programmieren"(also in Anführungszeichen). Ernsthaft?
Mit Java lässt sich viel besser arbeiten, als mit jeder anderen Sprache!

Dieser Post wurde am 01.08.2014 um 14:28 Uhr von A13XIS editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
01.08.2014, 20:59 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hehe jaja der böse compiler ;-)

Also gehen wir das ganze mal durch:

Punkt 1:
in Starter benutzt du GraphMan, GraphMan benutzt Starter.

Das Konstrukt sollte man software-design-technisch am besten vermeiden. Meist zeugen solche Abhängigkeiten von einem Fehler in der Programmier-Logik bzw in deinem Programm-Design.

Lösung: Beide Module zusammenlegen oder "hin und her" vermeiden.

Frage: Für was braucht der GraphMan denn den Starter?

Punkt 2:

"using namespace" im header ist böse, das erzeugt wenn du Pech hast seltsames Verhalten.

Lösung: lieber ein paar mal "man::" davor schreiben.

Punkt 3:
Forward-Deklarationen innerhalb von namespaces musst du logischerweise auch innerhalb eines namespaces forward deklarieren:


C++:
namespace man
{
   class GraphMan;
};



wäre die korrekte forward-deklaration für "man::GraphMan"

(using namespace direktiven greifen bei forward-declarationen nicht)


Punkt 4: (eigentlicher Punkt 0.5)

Zum Thema initialisierung.

In C++ hat jedes Objekt einen Konstruktor - d.h:


C++:
class test
{
public:
   test();
private:
   int a;
   other_class c;
   other_class2 d;
};

test::test()
{
  a = 5;
  c = other_class(12, 14);
  d = other_class2();
}



Im Konstruktor "test" werden implizit die Konstruktoren für die Membervariablen aufgerufen:

für "a" nicht, da dies ein integraler Typ ist. für "c" wird "other_class()" aufgerufen, für d "other_class2()"

Wenn nun jedoch "other_class" keinen parameterlosen (sichtbaren) Konstruktor hat, kann er diesen logischerweise nicht aufrufen.

Dafür gibt es eben "Initialisierungslisten" (angegeben mit dem doppelpunkt ).

Für obiges Beispiel wäre z.B sauberer:


C++:
test::test() : a(5), c(12, 14)
{
}



Hinweis: "d()" musst du nicht aufrufen, das wird automatisch gemacht.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.08.2014, 12:29 Uhr
A13XIS



Punkt 1
Diese "Ringabhängigkeit" (wie das Internet es genannt hat) brauche ich leider.
Starter ist die Hauptklasse in die die Module (grafik,audio und input) bedient.
dieselbe Abhängigkeit gibt es auch bei den anderen Modulen, was bedeutet, dass ich alles in eine Klasse zusammenlegen müsste, was sehr unübersichtlich ist.
Ich habe es aber gelöst in dem ich in Starter das #include aus dem Header gelöscht und die Module vordeklariert habe.Die includes müssen dann in die cpp-datei.

Punkt 2 ich habe das namespace ganz entfernt. Es nervt mehr als es nützt (zumindest bei einem so kleinen Programm)

Punkt 3 ist Damit geklärt

Punkt 4 Vielen Dank für die Erklärung

P.S. Habe ich schon erwähnt, dass mein CPP-Buch voll Phätt ist?
--
Java "Programmieren"(also in Anführungszeichen). Ernsthaft?
Mit Java lässt sich viel besser arbeiten, als mit jeder anderen Sprache!

Dieser Post wurde am 03.08.2014 um 12:30 Uhr von A13XIS editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
12.09.2014, 14:13 Uhr
ao

(Operator)



Zitat von A13XIS:
Punkt 1
Diese "Ringabhängigkeit" (wie das Internet es genannt hat) brauche ich leider.

Ja, aber man kann das Problem durch geschicktes Includieren umgehen.


Zitat:
Ich habe es aber gelöst in dem ich in Starter das #include aus dem Header gelöscht und die Module vordeklariert habe.Die includes müssen dann in die cpp-datei.

Richtig, genau so macht man das. In graphman.h muss man nicht wissen, wie Starter aufgebaut ist, sondern nur, dass es den Namen gibt und dass er eine Klasse definiert.

Entscheidend dafür ist, dass Graphman nicht von Starter erbt und kein Member vom Typ Starter hat. Member vom Typ "Pointer auf Starter" oder "Referenz auf Starter" stören nicht, die kann man deklarieren, ohne das Innenleben kennen zu müssen.

Eine Forward-Deklaration (class Starter ist in graphman.h also ausreichend.
 
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: