1

Je suis confronté à un problème d'utilisation de la déclaration forward, et je ne sais pas comment y remédier. Voici mes fichiers:Compilez l'heure "null" en utilisant la déclaration avant?

BubblePlug.h

#ifndef _BUBBLEPLUG_ 
#define _BUBBLEPLUG_ 

#include "IPlug_include_in_plug_hdr.h" 
#include "resource.h" 
#include "IControl.h" 

class IPianoRoll; 
class IMidiEngine; 

class BubblePlug: public IPlug 
{ 
private: 

public: 
    IMidiEngine *pMidiEngine; 
    IPianoRoll *pPianoRoll; 

    BubblePlug(IPlugInstanceInfo instanceInfo); 
    ~BubblePlug(); 
}; 

#endif // !_BUBBLEPLUG_ 

BubblePlug.cpp

#include "BubblePlug.h" 
#include "IPlug_include_in_plug_src.h" 
#include "IPianoRoll.h" 
#include "IMidiEngine.h" 

BubblePlug::BubblePlug(IPlugInstanceInfo instanceInfo) : IPLUG_CTOR(10, 1, instanceInfo) { 
    pPianoRoll = new IPianoRoll(this, 8, 8); 
    pMidiEngine = new IMidiEngine(this); 
} 
BubblePlug::~BubblePlug() { 
    delete pPianoRoll; 
    delete pMidiEngine; 
} 

IPianoRoll.h

#ifndef _IPIANOROLL_ 
#define _IPIANOROLL_ 

#include "IMidiEngine.h" 

class IPianoRoll : public IControl 
{ 
private: 
    BubblePlug *pBubblePlug; 

public: 

    IPianoRoll(BubblePlug *bubbleplug, int x, int y) : IControl(bubbleplug, IRECT(x, y, x + 10, y + 10)), pBubblePlug(bubbleplug) { 

    } 
    ~IPianoRoll() { 

    }; 

    bool Draw(IGraphics *pGraphics) { 
     return true; 
    } 

    void Random(bool onlyScore = false) { 
     pBubblePlug->pMidiEngine->Init(); 
    } 

    void Start() { 

    } 
}; 

#endif // !_IPIANOROLL_ 

IMidiEngine.h

#ifndef _IMIDIENGINE_ 
#define _IMIDIENGINE_ 

class IMidiEngine 
{ 
private: 
    BubblePlug *pBubblePlug; 

public: 
    IMidiEngine(BubblePlug *bubbleplug) : pBubblePlug(bubbleplug) { 

    } 
    ~IMidiEngine() { 

    }; 

    void Init(bool randomScore = true) { 
     pSamplwhk->pPianoRoll->Start(); 
    } 
}; 

#endif // !_IMIDIENGINE_  

quand je compile, il est dit autour pSamplwhk->pPianoRoll->Start();:

use of undefined type 'IPianoRoll' 
left of '->Start' must point to class/struct/union/generic type 

VS2015 trouver chaque élément écriture du code (je n'ai pas de problème), il arrive seulement quand je compile (Build).

Pourquoi? Je passe BubblePlug et je fais en avant de tous les deux IPianoRoll et IMidiEngine, en les incluant dans l'ordre (sur BubblePlug.cpp).

IMidiEngine devrait savoir tout ce qui concerne IPianoRoll (qui est inclus en premier).

Au moins, je devrais avoir un problème à "runtime", pourquoi à la compilation?

Pouvez-vous m'aider à comprendre le problème et comment y remédier? Merci.

+0

Essayez d'ajouter '#include" IMidiEngine.h "' à IPianoRoll.h – alexeykuzmin0

+0

@ alexeykuzmin0: J'ai modifié la question. Vérifiez-le! – markzzz

+1

Sans rapport: Vos gardes d'inclusion sont illégaux. https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier –

Répondre

1

IPianoRoll.h inclut IMidiEngine.h, donc peu importe dans quel ordre vous incluez les deux fichiers, la définition de IPianoRoll sera toujours après la fonction init où elle est utilisée.

Une façon d'éviter cela est de déplacer le corps de la fonction init dans un fichier séparé Cpp:

En IMidiEngine.h:

void Init(bool randomScore=true); 

En IMidiEngine.cpp:

void IMidiEngine::Init(bool randomScore) { 
    pSamplwhk->pPianoRoll->Start(); 
} 
+0

Maintenant, je vois quel est le problème. Comme il ajoute "une fois", IPianoRoll devient toujours après IMidiEngine. Donc IMidiEngine ne connaît pas la méthode Start d'IPianoRoll, n'est-ce pas? Pourquoi spearate les fichiers va résoudre le problème? C'est ce que je ne connais pas. Au moment de la compilation d'abord si include .h, que "compiler" .cpp? – markzzz

+1

Vous devez vous assurer que la définition d'une classe est vue avant de pouvoir l'utiliser. Ma solution suggérée est la suivante: elle déplace le corps de la fonction vers un point ultérieur de la compilation, où les deux définitions ont déjà été vues par le compilateur. –

+1

@paizza - Dans le fichier .cpp * tout * est inclus en premier - si visible dans les corps de la fonction. Dans un fichier d'en-tête, vous ne pouvez pas voir ce qui vient dans l'en-tête suivant. –