Frage

Ich bin mit einer 3rd-Party-Bibliothek, die eine Erklärung, wie diese hat:

typedef struct {} __INTERNAL_DATA, *HandleType;

Und ich möchte eine Klasse erstellen, die eine Handle im Konstruktor:

class Foo
{
    Foo(HandleType h);
}

ohne , einschließlich der Header, die Handle definiert. Normalerweise würde ich nur voraus erklären, eine solche Art, aber ich kann die Syntax für diese nicht herausfinden. Ich möchte wirklich etwas sagen wie:

struct *HandleType;

Aber das sagt "Expected-Kennung vor *" in GCC. Die einzige Lösung, die ich sehen kann, ist meine Klasse wie folgt zu schreiben:

struct __INTERNAL_DATA;
class Foo
{
    Foo(__INTERNAL_DATA *h);
}

Aber dies stützt sich auf interne Details der Bibliothek. Das heißt, es den Namen __INTERNAL_DATA verwendet, die eine Implementierung Detail.

Es scheint, wie es möglich sein sollte, um Handle (Teil der öffentlichen API) voraus deklarieren, ohne __INTERNAL_DATA mit (Teil der Implementierung der Bibliothek.) Wer weiß, wie?

EDIT:. Hinzugefügt ausführlicher über das, was ich suche

War es hilfreich?

Lösung

Update:

  

ich es bei der Umsetzung von CPP Foo verwenden, aber ich mag für Foo einschließlich es in meinem Kopf .h zu vermeiden. Vielleicht bin ich einfach nur zu umständlich? :)

Ja, Sie sind :) Go ahead mit Forward-Deklaration.

Wenn Handelte Teil der Schnittstelle ist es muss ein Header, erklärt sein. Verwenden Sie diesen Header.

Ihr Problem ist nach wie vor ein vage. Sie versuchen, etwas zu schützen, gegen Sie nicht können.

Sie können die folgende Zeile in der Client-Bibliothek hinzufügen:

typedef struct INTERNAL_DATA *HandleType;

aber, wenn der Name / Struktur ändert Sie für einige Gießen Bösartigkeit sein kann.

Try-Vorlagen:

template <class T>
class Foo
{
    Foo(T h);
};

Forward-Deklaration ist in Ordnung. Wenn Sie vorhaben, Zeiger oder Verweise zu verwenden, müssen Sie nur eine Klasse (__INTERNAL_DATA) Erklärung im Umfang. Wenn Sie jedoch eine Member-Funktion oder ein Objekt verwenden wollen, müssen Sie den Header enthalten.

Andere Tipps

Wenn der Typ in einer 3rd-Party-Bibliothek wird dann der große Vorteil der Vorwärtsdeklaration (Erneuerungen aufgrund von Änderungen in Header zu isolieren) wirksam verloren.

Wenn Sie besorgt über Kompilierungszeiten (es ist ein beträchtlicher Header), dann vielleicht können Sie es in einem vorkompilierte Header platzieren oder fügen Sie einfach die entsprechenden Header aus einer Bibliothek.

z. viele Bibliothek Header aussehen

// library.h
#include "Library/Something.h"
#include "Library/SomethingElse.h"
 typedef struct {} __INTERNAL_DATA, *HandleType;

Wenn es so, dass ein (alles in einer Zeile) definiert ist, dann __INTERNAL DATA ist ebenso ein Teil der öffentlichen Schnittstelle als Handle.

Aber ich glaube nicht, __INTERNAL_DATA tatsächlich existiert. Mehr als wahrscheinlich, ist wirklich Handle (intern) ein int. Diese seltsame Definition ist nur ein Weg, es zu definieren, so dass es die gleiche Größe wie ein int ist, aber deutlich, so dass der Compiler einen Fehler geben, wenn Sie einen int versuchen vorbei, wo man angeblich ist einen Handle passieren. Die Bibliothek Anbieter könnten genauso gut haben es als „int“ oder „void *“ definiert, aber auf diese Weise wir eine Art Kontrolle zu bekommen.

Daher __INTERNAL_DATA ist nur eine Konvention und nicht ändern wird.


UPDATE: Die oben war ein bisschen eine mentale rülpsen ... OK, __INTERNAL_DATA definitiv nicht existiert. Wir wissen, dass dies für eine Tatsache, denn wir können sehen es die Definition als eine leere Struktur. Ich werde erraten, dass die 3rd-Party-Bibliothek verwendet "C" externe Bindung (kein Name managling), wobei in diesem Fall kopieren Sie einfach die typedef -. Es wird gut

Im Inneren der Bibliothek selbst, Handle wird haben eine ganz andere Definition; vielleicht int, vielleicht "struct MyStruct {.......} *".

Wenn Sie wirklich, wirklich, wirklich nicht wollen, _INTERNAL_DATA dem Anrufer dann Ihre einzige wirkliche Wahl zu belichten ist verwenden typedef void * Handle ; Dann in Ihrer Bibliothek können Sie tun, was Sie die gesamte Implementierung * Handle Ändern einschließlich sollen.

Erstellen Sie einfach eine Hilfsfunktion Sie echte Daten zugreifen zu können.

inline _INTERNAL_DATA* Impl(HandleType h) {
    return static_cast<_INTERNAL_DATA*>(h);
}

Ich bin mir nicht ganz sicher, was Sie vorhaben, für, aber die folgende funktionieren wird, ohne dass die tatsächliche Header-Datei einschließlich:

// foo.h
class Foo
{
    public:
    template<typename T>Foo(T* h) { /* body of constructor */ }
};

Wohlgemerkt, werden Sie noch Zugang der Öffentlichkeit Mitglieder der __INTERNAL_DATA innerhalb des Körpers des Konstrukteurs haben müssen.

bearbeiten. , wie von James Curran, die __INTERNAL_DATA Struktur hat keine Mitglieder darauf hingewiesen, so kann es verwendet werden, wie oben beschrieben, ohne Probleme

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top