Frage

Ich muss Zeiger in Long (sendMessage ()) konvertieren und möchte sicher überprüfen, ob die Variable auf der anderen Seite korrekt ist.Also habe ich darüber nachgedacht, „dynamic_cast“ zu machen, aber das funktioniert nicht bei Klassen, die nicht virtuell sind.Dann habe ich darüber nachgedacht, typeid zu verwenden, aber das wird funktionieren, bis ich eine abgeleitete Variable als Basis übergebe.

Gibt es eine Möglichkeit zu überprüfen, ob der Zeiger zur Laufzeit meinen Erwartungen entspricht?Gibt es eine Möglichkeit, mit typeid zu sehen, ob ein Zeiger ein von einer bestimmten Basis abgeleiteter Typ ist?

War es hilfreich?

Lösung

Wenn Sie nur ein haben long, dann kann man eigentlich nicht viel machen.Es gibt keine allgemeine Möglichkeit zu bestimmen, ob eine beliebige Zahl eine gültige Speicheradresse darstellt.Und selbst wenn Sie wissen, dass es sich um eine gültige Speicheradresse handelt, gibt es keine Möglichkeit, den Typ des Objekts zu bestimmen, auf das der Zeiger zeigt.Wenn Sie nicht sicher sein können, um welchen tatsächlichen Typ es sich handelt, bevor die Adresse zugewiesen wurde long, dann können Sie nicht sicher sein, dass das Wirken sicher ist long zu welchem ​​Typ auch immer Sie es umwandeln möchten.

Sie müssen lediglich darauf vertrauen, dass der Absender der Nachricht Ihnen einen gültigen Wert gesendet hat.Das Beste, was Sie tun können, ist, einige Vorsichtsmaßnahmen zu treffen, um die Konsequenzen für Ihr eigenes Programm zu verringern, wenn es einen falschen Wert erhält.

Andere Tipps

Ihr Verweis auf SendMessage() Ich höre mich an, als wäre MS Windows Ihre Plattform und dann die Regeln für die Verwendung von Zeigern (Windows) wird empfohlen. Es beschreibt die PtrToLong und PtrToUlong Funktionen und andere Dinge, die Microsoft in solchen Situationen für Sie zur Verfügung stellen.

Sie können TypId nicht verwenden. Dies führt zu einem Zugriffsverletzung, wenn Sie Müll anstelle eines gültigen Zeigers erhalten, sodass Ihr Scheck unsinnig ist.

Was Sie tun sollten, ist, dass Sie Ihre SendMessage und den Code einwickeln, der die Nachricht in eine einzelne Typ-Safe-Schnittstelle verarbeitet. Auf diese Weise können Sie unerwartete Dinge nicht an sendMessage übergeben und benötigen keine Schecks auf der Empfangsseite.

C ++ -Stypsystem funktioniert zur Kompilierungszeit. Sobald Sie einen Zeiger auf lange Sicht geworfen haben, verlieren Sie alle Typinformationen. Eine lange ist einfach so viele Teile im Gedächtnis; Es gibt keine Möglichkeit, dass Sie auf ein Objekt hinweisen.

Ptlib ( http://sourceforge.net/projects/opalvoip/ ) verwendet ein PCASSINFO -Makro, um die Beziehungen zwischen Klassen zu definieren. Dies bietet Funktionen wie Isdescendant und GetClass.

Sie könnten wahrscheinlich etwas Ähnliches implementieren.

dynamic_cast funktioniert die Signatur der virtuellen Methode Tabelle. Wenn Sie keine virtuellen Methoden haben, haben Sie keine VMT. Wenn Sie also sagen, dass dynamic_cast nicht funktioniert. Wenn Sie jedoch keine VMT haben, haben Sie absolut kein Wissen darüber, dass das Objekt darauf hingewiesen wird.

Am besten verlangt es, dass Zeiger für Klassen mit mindestens einer virtuellen Methode teilnehmen, auch wenn es sich um einen Dummy handelt. Dynamische Besetzung wird dann funktionieren.

Ich verstehe noch nicht, worum es bei deiner Frage geht.

  • Ob dies der Fall ist oder nicht, Sie können sicher sein, dass das Werfen auf eine lange und eine hintere Linie den gleichen Wert ergibt Den Typ einer Variablen sicher überprüfen
    Angesichts der „Regeln für die Verwendung von Zeigern“ der MS-Site, auf die der andere Antwortende verlinkt hat, ist der richtige Typ für die Umwandlung UINT_PTR.Also tust du es UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr); um ihn in einen ganzzahligen Typ umzuwandeln, und führen Sie den umgekehrten Vorgang aus, um ihn erneut auf den Zeiger umzuwandeln.Der C++-Standard garantiert, dass der ursprüngliche Wert wiederhergestellt wird.(Siehe den Link, den ich oben angegeben habe, für meine Erklärung dazu).Auf dieser Microsoft-Seite heißt es übrigens auch, dass WPARAM und LPARAM ihre Größe je nach Plattform ändern.Sie könnten also einfach diese Variable verwenden v Und SendMessage Es.
  • Wenn Sie auf diese Weise auf der anderen Seite überprüfen können, ob der Zeiger (in einen Zeigertyp konvertiert) auf ein Objekt zeigt, lautet die Antwort Du kannst nicht.Da Sie offenbar nicht sicher sind, welcher Zeigertyp zum Senden verwendet wurde, können Sie auf der Empfängerseite nicht überprüfen, auf welchen dynamischen Typ der Zeiger zeigt.Wenn Sie wissen, welchen Typ der Zeiger auf der Senderseite hatte, wäre Ihre Prüfung gar nicht erst erforderlich.

In Windows bietet MFC eine Methode zum Überprüfen, ob ein bestimmter Zeiger auf einen gültigen Speicherort verweist (dies erfolgt durch Einfangen von SEGFAULT). Ich erinnere mich nicht an den Funktionsnamen, aber er ist da. Dennoch stellt es nicht sicher, dass der Inhalt des Speichers gültig ist. Es kann noch ungültige VMT haben und Ihren Code abstürzen. Natürlich können Sie den Segfault selbst einfangen (Siehe MS -Wissensbasis)

Wenn Sie überprüft werden, ob etwas zu einem Typ gehört, müssen Sie zunächst eine Basisklasse haben. Wenn Sie den Destruktor der Basisklasse "virtuell" machen, haben alle abgeleiteten Klassen VMTs.

Wenn Sie VMT um jeden Preis vermeiden müssen, müssen Sie eine Art Dekriminator haben, der Ihnen mitteilt, was Sie zu tun haben, z. B. Ereignisart bei MS Windows -Events.

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