[C++] Klassen referenzieren

r00t~

Lt. Junior Grade
Registriert
Jan. 2011
Beiträge
341
Guten Morgen,

Hab vor einigen Monaten in Java ein kurzes Spiel geschrieben. Da ich C++ lernen möchte, habe ich mir vorgenommen, den Code in C++ "umzuschreiben", so gut eben möglich (Habe den Großteil meiner Java-Kenntnisse durch Umschreiben von Python-Code in Java). Nach Anpassung des Glut-Besipiels komme ich bei der Referenzierung der Klassen untereinander nicht weiter: Es soll eine Instanz der Klasse "Engine" erzeugt werden, welche wiederum jeweils eine Instanz der Klassen "Player" und "Balls" erzeugen soll. Dabei soll diesen Instanzen eine Referenz auf die Klasse Engine übergeben werden. Bei dem jetzigen Code erscheinen die Fehlermeldungen "field 'ref' has incomplete type" und "field 'player' hasincomplete type".

Ausschnitt aus dem main-Teil:
Code:
#include "include/Player.h"
#include "include/Balls.h"
#include "include/Engine.h"
(...)
Engine engine;

Engine Header:
Code:
#ifndef ENGINE_H
#define ENGINE_H

#include "Player.h"
#include "Balls.h"

class Player;
class Balls;

class Engine
{
    public:
        inline Engine();
        inline void readyUp();
        //~Engine(){};
    private:
        Player player;
        Balls balls;
        double delta_t;
        int balls_survived;
        bool question_restart;
};

#endif // ENGINE_H

Engine Source:
Code:
#include "../include/Engine.h"

Engine::Engine()
{
    delta_t = 0.001;
    balls_survived = 0;
    question_restart = false;

}
void Engine::readyUp()
{
    player = new Player(this);
    balls = new Balls(this);
}

Player Header:
Code:
#ifndef PLAYER_H
#define PLAYER_H

#include "Engine.h"
class Engine;

class Player
{
    public:
        Player(Engine);
    protected:
    private:
        Engine ref;
};

#endif // PLAYER_H*/

Player Source:
Code:
#include "../include/Player.h"

Player::Player(Engine pref)
{
    ref = pref;
}

Balls Header:
Code:
#ifndef BALLS_H
#define BALLS_H

#include "Engine.h"
class Engine;

class Balls
{
    public:
        Balls(Engine);
    protected:
    private:
        Engine ref;
};

#endif // BALLS_H

Balls Source:
Code:
#include "../include/Balls.h"

Balls::Balls(Engine pref)
{
    ref = pref;
}

Bitte um Rat!
 
Du nutzt this (Zeiger auf das aktuelle Objekt) als Übergabe, erwartet wird aber ein Objekt. Setz dich mal mit Zeigern auseinander. Du würdest hier nämlich nur eine Kopie des Objekts übergeben und wenn du was im Original änderst, bleibt die Kopie unberührt.
 
Zusätzlich verwendest du forwarddeklaration und dann willst du aber eine Instanz anlegen

Code:
   #ifndef BALLS_H
    #define BALLS_H
    #include "Engine.h"
    class Engine;
     
    class Balls
    {
    public:
        Balls(Engine);
    protected:
    private:
        Engine ref;
    };
    #endif // BALLS_H
in Zeile 4 sagst du dem Compiler das es eine classe mit dem Namen Engine gibt..
In Zeile 11 willst du aber eine Instanz von dem Object anlegen, dazu braucht aber der Compiler nicht nur den Namen sondern auch Information wie gross es ist (sonst kann er ja keinen speicher reservieren)

du müsstest entweder schreiben
Engine *ref; oder wenn es sich während der Lebenszeit nicht mehr ändert
Engine &ref;

bei zweiteren müsstest den Consturctor anpassen der sollte dann ungefähr so aussehen
Code:
Balls::Balls(Engine &pref):
ref(pref)
{}
 
Habe jetzt bei "Player" und "Balls" den Typen "Engine" zu "Engine*" geändert, damit der Wert von this als Zeiger gespeichert wird. Nun erhalte ich die Fehlermeldung "field 'player' has incomplete type". Ist die Klassendeklaration unvollständig oder hängt das evtl mit dem Zeiger zusammen?

E: @the_nobs:
Die Klasse Engine ändert sich während der Lebenszeit noch. Bekomme mit der Zeigervariante die "incomplete type" Fehlermeldung.
Ergänzung ()

Glaub ich habs, zumindest keine Fehlermeldungen mehr...
 
Zuletzt bearbeitet:
r00t~ schrieb:
Engine Header:
Code:
#ifndef ENGINE_H
#define ENGINE_H

#include "Player.h"
#include "Balls.h"

class Player;
class Balls;

class Engine
{
    public:
        inline Engine();
        inline void readyUp();
        //~Engine(){};
    private:
        Player player;
        Balls balls;
        double delta_t;
        int balls_survived;
        bool question_restart;
};

#endif // ENGINE_H

Engine Source:
Code:
#include "../include/Engine.h"

Engine::Engine()
{
    delta_t = 0.001;
    balls_survived = 0;
    question_restart = false;

}
void Engine::readyUp()
{
    player = new Player(this);
    balls = new Balls(this);
}

Noch eine Kleinigkeit. Du hast deine readyUp()-Methode als inline deklariert. Wenn sich dein Compiler jetzt tatsächlich entscheidet, dieser Bitte Folge zu leisten und einen Aufruf dieser Methode in einer anderen Übersetzungseinheit inlinen möchte, wird er das nicht können, da die Definition der Methode in Engine.cpp liegt, welche in anderen Übersetzungseinheiten nicht sichtbar ist. Entweder

  1. das inline wegnehmen ODER
  2. die Definition der Methode in den Header verlagern ODER
  3. sicherstellen, daß der einzige Aufrufer der Methode die Übersetzungseinheit Engine.cpp selbst ist


P.S. Gleiches gilt auch für den als inline deklarierten Konstruktor.
 
Zurück
Oben