klassen brauchen gegenseitig bezug aufeinander



  • Hallo!

    Ich soll ein Codefragment aus einer Anleitung benutzen, wobei es aber zu oben beschriebenem Phänomen kommt:

    class CVideoInputPin
    	: public CRendererInputPin
    {
    	CBitmapRenderer *m_pRenderer;       // The renderer that owns us
    	CCritSec *m_pInterfaceLock;         // Main filter critical section
    
    public:
    
    	// Constructor
    
    	CVideoInputPin(
    		TCHAR *pObjectName,             // Object string description
    		CBitmapRenderer *pRenderer,     // Used to delegate locking
    		CCritSec *pInterfaceLock,       // Main critical section
    		HRESULT *phr,                   // OLE failure return code
    		LPCWSTR pPinName);              // This pins identification
    
    	virtual HRESULT GetMediaType( int iPosition, CMediaType* pMediaType );
    };
    
    class CBitmapRenderer
    	: public CBaseVideoRenderer
    {
    public:
    
        // Constructor and destructor
    
        static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *);
        CBitmapRenderer(TCHAR *pName,LPUNKNOWN pUnk,HRESULT *phr);
        ~CBitmapRenderer();
    
        DECLARE_IUNKNOWN
    
        void SetCallback( IBitmapCallback* pcb )
        {
            m_Callback = pcb;
        }
    
        // Override these from the filter and renderer classes.  I strongly
    	// suspect we don't need BreakConnect/CompleteConnect either.
    
        HRESULT BreakConnect();
        HRESULT CompleteConnect(IPin *pReceivePin);
        HRESULT SetMediaType(const CMediaType *pmt);
        HRESULT CheckMediaType(const CMediaType *pmtIn);
        HRESULT DoRenderSample(IMediaSample *pMediaSample);
        void OnReceiveFirstSample(IMediaSample *pMediaSample);
    
    public:
    	CVideoInputPin  m_InputPin;        // IPin based interfaces
        CMediaType      m_mtIn;            // Source connection media type
        SIZE            m_VideoSize;       // Size of the current video stream
        IBitmapCallback* m_Callback;
    
    }; // CBitmapRenderer
    

    Wie Ihr seht, benutzt die erste Klasse eine Variable des Typs der 2. Klasse und diese ebenso eine des Typs der ersten.
    Außerdem macht mich das doppelte public: im 2. COde-Teil stutzig.
    Habt Ihr eine Idee, was da falsch läuft? oder kann man die evtl. in Borland entgegen der allgemeinen Regel doch irgendwie gleichzeitig definieren?^^
    Übrigens muss ich dafür dShow.h und streams. vom DirectShow einbinden. irgendwie kam ich auch an eine extra dshow.h-Datei, in der die 2. Klasse definiert ist (Allerdings grob anders) und deren einbinden natürlich in Fehler wegen doppelter Definition endet.

    Ich benutze Embarcadero C++Builder XE2 Version 16, das müsste C++-Builder 2006/6 sein, denke ich...

    mit freundlichen Grüßen
    Julian



  • Hallo

    Dafür brauchst du nur eine passende Forward Declaration. Um die Reihenfolge zu erläutern, hier die Struktur

    class CBitmapRenderer; // Notwendige Forward Declaration
    // Ab hier kann CBitmapRenderer für Deklarationen von Zeigern und Referenzen
    // Benutzt werden. Um die Implementation verwenden zu können, ist dann wieder
    // die komplette Deklaration von CBitmapRenderer notwendig. Eine saubere und
    // durchdachte Aufteilung in Header- und Implementationsdateien wird 
    // vorausgesetzt
    
    class CVideoInputPin
    {
        CBitmapRenderer *m_pRenderer;       // The renderer that owns us
    
    };
    
    // Jetzt kommt die vollständige Deklaration
    class CBitmapRenderer
        : public CBaseVideoRenderer
    {
        CVideoInputPin  m_InputPin;        
    
    };
    

    Das doppelte public ist technisch kein Problem. Allerdings soll in deinem Fall das zweite public vermutlich ein private sein.

    bis bald
    akari



  • Wow, vielen Dank für die schnelle (und anscheinend richtige) Lösung!
    Wobei ich es schon seltsam finde, dass es dabei nicht auch zu Mehrfachdefinitionsfehlermeldungen kommt^^

    Kann es aber nicht eigentlich bei der Verwendung der Klassen in Variabeln durch die Konstruktoren zu Endlosschleifen kommen?

    Das mit public lasse ich erstmal so, denke ich... doppelte Variablenbenennung kommt nicht vor und die Klasse soll sowieso nicht weitergegeben werden^^



  • Hallo

    Dediggefedde schrieb:

    Wobei ich es schon seltsam finde, dass es dabei nicht auch zu Mehrfachdefinitionsfehlermeldungen kommt^^

    Das ist eben der Unterschied zwischen einer Deklaration und einer Definition.
    Du darfst mehrmals deklarieren, aber nur einmal definieren. Solange die Deklarationen alle auf den exakt gleichen Typ verweisen, funktionierts.

    Kann es aber nicht eigentlich bei der Verwendung der Klassen in Variabeln durch die Konstruktoren zu Endlosschleifen kommen?

    Wenn Klasse A im Konstruktor immer eine Instanz der Klasse B erzeugt und Klasse B im Konstruktor immer eine Instanz der Klasse A - dann ja.
    Aber in deinem Beispiel hat Klasse CVideoInputPin im Konstruktor nur einen Verweis (einen Zeiger) auf eine bereits existierende Instanz der Klasse CBitmapRenderer. Es wird keine neue Instanz erstellt.

    bis bald
    akari


Anmelden zum Antworten