2016-04-12 16 views
1

Gibt es eine Möglichkeit, einen Zeiger des aktuellen Objekttyps mit dem Schlüsselwort 'this' oder ähnlichem zu erstellen, so dass der Klassentyp nicht explizit erwähnt wird?Erstellen Sie einen Zeiger vom Typ 'this'/current object

Ich habe eine Basisklasse GraphicObjects, die als Container für andere GraphicObjects und von GraphicObjects abgeleitete Objekte dienen kann. Ich dachte, das wäre vielleicht besser gewesen, als den Typ in der Klasse explizit zu benennen, damit ich ihn woanders verwenden/die Klassennamen ändern kann.

Wenn es möglich ist, gibt es Gründe, dieses nicht zu verwenden?

+5

Was möchten Sie erreichen? 'typeid' gibt ein' std :: type_info' * Objekt * zurück. Haben Sie es mit C++ 11 [decltype] (http://en.cppreference.com/w/cpp/language/decltype) verwechselt? Sachen wie 'typenname std :: remove_reference :: type a;' ist in * methoden * absolut gültig, aber ... naja ... – dhke

+0

Vorlagen können dich wahrscheinlich retten, aber warum ist es so? nicht nur möglich, Alpha zu schreiben? Wenn es nur eine Frage oder eine Vorliebe ist, dann würde ich sagen "es ist Teil der Sprache, hack nicht herum". – MicroVirus

+0

@Michael Ich habe eine Basisklasse GraphicObjects, die als Container für andere GraphicObjects und von GraphicObjects abgeleitete Objekte dienen kann. Ich dachte, das wäre vielleicht besser gewesen, als den Typ in der Klasse explizit zu benennen, damit ich ihn woanders verwenden/die Klassennamen ändern kann. –

Antwort

1

C++ ist eine kompilierte Sprache mit einem meist statischen Systemtyp. Insbesondere hat jeder Ausdruck einen Typ, der zur Kompilierungszeit bestimmt wird. Zum Beispiel wird in den Funktionen GraphiObjects der this Zeiger vom Typ GraphiObjects*, möglicherweise mit const und/oder volatile hinzugefügt.

Jetzt gibt es auch so etwas wie einen "Laufzeittyp", weil C++ eine OO-Sprache ist. Weil this ein GraphiObjects* Zeiger ist, kann er auf ein GraphiObjects Objekt zeigen, aber auch auf ein Objekt einer abgeleiteten Klasse. typeid unterstützt Laufzeitabfragen, aber Sie versuchen, es zur Kompilierungszeit zu verwenden.

Sie können decltype(*this) mit Elementfunktionen verwenden, aber Sie können es nicht für Elementdaten verwenden. Das macht Sinn: const Methoden haben eine Const-qualifizierte this Zeiger, nicht-Konstanten Methoden nicht, aber für ein Datenelement gibt es keine Möglichkeit zu bestimmen, ob this Const-qualifiziert sein sollte.

+0

Danke für die Erklärung. –

+0

C++ ist keine "OO-Sprache" (obwohl das ein Paradigma ist, das es unterstützt), und das bedeutet nicht, dass es keine Laufzeittypen gibt. Python ist eine OO-Sprache und hat Runtime-Typen, daher bin ich mir nicht sicher, was Sie in Ihrem zweiten Absatz sagen wollen. –

+0

@TobySpeight: In C++, "dynamischer Typ" bedeutet nicht, dass Typen zur Laufzeit erstellt werden. Es wird speziell in Kontexten verwendet, in denen ein Ausdruck auf ein Objekt verweist und der Typ des Objekts nicht mit dem Typ des Ausdrucks übereinstimmt. In diesem Fall wird der Typ des Ausdrucks als statischer Typ und der Typ des Objekts als dynamischer Typ bezeichnet, und der erste Typ ist normalerweise eine Basisklasse des letzteren (wobei "void *" ignoriert wird). Dies hängt mit C++ ''dynamic_cast' zusammen. – MSalters

1

Gibt es eine Möglichkeit, einen Zeiger des aktuellen Objekttyps zu erstellen?

Ja, this. Das Erstellen einer Membervariablen, die this repliziert, ist bestenfalls verschwenderisch.

Ich habe eine Basis class GraphicObjects, die als Container für andere GraphicObjects und Objekte, die von GraphicObjects

wirken kann Bitte tun dies nicht. Erstellen Sie Ihre Objekthierarchie und verwenden Sie einen Standardcontainer, um sie zu enthalten. Andernfalls enthalten jedes Ihrer Objekte, auch die Nicht-Basisobjekte, ein leeres children_ Mitglied sowie alle anderen Mitglieder und Funktionen, die für die Bearbeitung erforderlich sind. Dies ist verschwenderisch und verwirrend.

Ich dachte, dies könnte besser gewesen sein, als den Typ in der Klasse explizit zu benennen, damit ich es woanders verwenden/die Klassennamen ändern kann.

Da Sie Klassen verwenden, die sich alle in der Hierarchie GraphicObjects befinden, sollten Sie die Vorteile polymorphisim nutzen. Sie können auf alle Objekte in dieser Hierarchie mit einer GraphicObjects* verweisen. Und das Abrufen des Objekttyps ist so einfach wie ein dynamic_cast.

ich ein ziemlich ausführliches Beispiel geschrieben haben, die Verwendung von polymorphisim mit einem Behälter hier zu demonstrieren: http://ideone.com/XSjMHW

EDIT:

  1. Nicht alle Ihre Objekte andere Objekte enthalten wird, diese Knotenobjekte was nichts enthalten sollte von einem Typ sein, nennen wir es class Node, , die keine anderen Objekte enthält
  2. Andere Objekte möglicherweise ihr eigener Ausdruck, sondern auch andere Objekte enthalten, werden diese von einem separaten Typ sein sollte, rufen wir es class Container, entweder Container von Node oder hat ein Mitglied erben kann Node, es enthält andere Node s auch/Container s
+0

Danke für die Informationen und das Beispiel.Ich meinte einen Zeiger ** von ** dem aktuellen Typ und nicht ** bis ** dem aktuellen Objekt. Ein bisschen über den Rahmen meiner ursprünglichen Frage hinaus, aber ich habe ein grafisches Textobjekt, das von GraphicObject erbt. Ich habe dann ein Button-Objekt, das ein Text-Objekt sowie einen eigenen Zeichencode für das Button-Gesicht enthält. Dann ein Screen/Form-Objekt, das null oder mehr Grafikobjekte enthalten kann. Würden Sie GraphicObject ohne einen Container behalten und nur einen Container in jedem der abgeleiteten Objekte haben? Ich dachte an eine sehr reduzierte Version der .NET-Control-Klasse –

+0

@ mattb5906, die ich bearbeitet habe, um zu versuchen, einen objektiven Weg zu klären, wie man die Klassenstruktur einrichtet, die Sie darstellen. Lassen Sie mich wissen, ob das Sinn macht. –

+0

Das ist großartig. Danke für das. –