Kann eine C++-Klasse sich selbst als Mitglied aufnehmen?

Lesezeit: 4 Minuten

Kann eine C Klasse sich selbst als Mitglied aufnehmen
Peter Steward

Ich versuche, eine Python-Routine zu beschleunigen, indem ich sie in C++ schreibe und sie dann mit ctypes oder cython verwende.

Ich bin ganz neu in c++. Ich verwende Microsoft Visual C++ Express, da es kostenlos ist.

Ich plane, einen Ausdrucksbaum und eine Methode zu implementieren, um ihn in Postfix-Reihenfolge auszuwerten.

Das Problem, auf das ich sofort stoße, ist:

class Node {
    char *cargo;
    Node left;
    Node right;
};

Ich kann nicht deklarieren left oder right als Node Typen.

  • Ich kann links oder rechts nicht als Knotentypen deklarieren.” Dies sollte eine Erklärung enthalten, warum, mit wörtlichen Zitaten aller erhaltenen Fehler. Vermutlich hat sich Ihr Compiler über etwas wie beschwert Node zu diesem Zeitpunkt ein unvollständiger Typ zu sein.

    – Unterstrich_d

    21. November 2019 um 13:34 Uhr

Nein, denn das Objekt wäre unendlich groß (weil jede Node hat als Mitglieder zwei andere Node Objekte, die jeweils zwei andere als Mitglieder haben Node Objekte, die jeder … na ja, Sie verstehen schon).

Sie können jedoch einen Zeiger auf den Klassentyp als Mitgliedsvariable haben:

class Node {
    char *cargo;
    Node* left;   // I'm not a Node; I'm just a pointer to a Node
    Node* right;  // Same here
};

  • In diesem Fall ist ein bloßer Zeiger die richtige und intuitive Wahl. Es ist erwähnenswert, dass es andere Möglichkeiten sein kann, mich als Mitglied zu halten, wie zum Beispiel: reference, std::unique_ptr, std::shared_ptr oder std::weak_ptrsiehe auch: stackoverflow.com/questions/63365537/c-instance-of-same-class/…

    – Amir Kirsch

    12. August 2020 um 9:15 Uhr

Beachten Sie nur der Vollständigkeit halber, dass eine Klasse eine statische Instanz von sich selbst enthalten kann:

class A
{
    static A a;
};

Dies liegt daran, dass statische Member nicht wirklich in den Klasseninstanzen gespeichert werden, sodass es keine Rekursion gibt.

  • Das hat mich ein wenig auf den Kopf gestellt, also würde ich etwas hinzufügen: In diesem Fall speichert jede Instanz der Klasse ‘A’ nur einen Zeiger auf einen Platz, der im statischen Speicher für die bestimmte Instanz ‘a’ zugewiesen ist. Die ‘a’-Instanz hat also auch einen Zeiger, der unendlich auf sich selbst zeigt: A* someA = new A; someA->.a.a.a...etc. (vorausgesetzt, ‘a’ ist ein öffentliches Attribut) und deshalb wird der Speicher endlich verwendet.

    – gesungen

    29. November 2017 um 13:45 Uhr


  • @hymced: Nein, keine der Instanzen von A enthält einen Zeiger, sicherlich nichts, das auf das statische Mitglied zeigt. -> und . erhalten Sie dieses Objekt dank Namenssuchregeln, nicht aufgrund eines Speicherlayouts.

    – Leichtigkeitsrennen im Orbit

    19. Juli 2019 um 16:08 Uhr


  • @Lightness-Races-in-Orbit Sie haben Recht, im obigen Beispiel gibt es keine Hinweise. Was ich meinte, ist, dass der verwendete Speicher endlich ist, nicht weil das statische Mitglied außerhalb der Klasseninstanz gespeichert wird, sondern weil dieses bestimmte statische Mitglied für jede Klasseninstanz gleich ist. Das liegt auch daran, dass die ´a´-Instanz nur sich selbst enthält und sonst nichts. Fügen Sie der Mischung ein einfaches (nicht statisches) int-Member hinzu, Sie haben selbst mit einem statischen Klassenmitglied nicht genügend Arbeitsspeicher.

    – gesungen

    20. Juli 2019 um 19:17 Uhr

  • @hymced Das stimmt einfach nicht. Warum denkst du das Hinzufügen eines Nicht-static int Mitglied zu A würde dazu führen, dass dem Computer der Arbeitsspeicher ausgeht?

    – Leichtigkeitsrennen im Orbit

    20. Juli 2019 um 19:32 Uhr


  • Wieder habe ich mich geirrt: ‘A’ hätte ein int-Mitglied (nicht im statischen Speicher) anders als ‘a’ (im statischen Speicher), aber das int-Mitglied von ‘a’ wäre das gleiche wie ‘aa’ (da ‘ aa’ IST ‘a’), dasselbe wie ‘aaa’ usw. Der verwendete Speicher ist also endlich.

    – gesungen

    21. Juli 2019 um 20:21 Uhr

Nein, aber es kann eine Referenz oder einen Zeiger auf sich selbst haben:

class Node
{
    Node *pnode;
    Node &rnode;
};

  • Referenzen funktionieren in diesem Fall nicht wirklich, da sie nicht null sein dürfen und Sie Nullenden benötigen oder der Graph unendlich wäre.

    – Blind

    24. April 2010 um 21:17 Uhr

  • Sie könnten einen Dummy-Knoten erstellen, um das Tempo von NULL zu übernehmen. Dies funktioniert jedoch nicht gut, da Verweise nicht auf etwas anderes neu zugewiesen werden können und die Änderung eines Links die Rekonstruktion aller Knoten bis zur Wurzel erfordern würde.

    – Kartoffelklatsche

    24. April 2010 um 21:32 Uhr

  • @Blindy: Sie könnten auch die Knotenreferenz auf setzen *this statt NULL.

    – MSalter

    26. April 2010 um 12:38 Uhr

  • @Blindy, @All: Ja. Wie gesagt, ich bin ein echter Anfänger. Ich hatte eine sehr schwierige Zeit, dies zusammenzubringen.

    – Peter Steward

    26. April 2010 um 23:10 Uhr

  • @Blindy aber es gibt std::optional< std::reference_wrapper<Node> >! Lachen Sie nicht. Es ist einfacher zu werfen, wenn es ‘null’ ist, und weniger anfällig für versehentliche Zeigerarithmetik und dergleichen.

    – Unterstrich_d

    21. November 2019 um 13:32 Uhr

1646983809 698 Kann eine C Klasse sich selbst als Mitglied aufnehmen
Amit G.

Verwenden Sie einen Zeiger, & besser initialisiert:

class Node {
    char * cargo = nullptr;
    Node * left = nullptr;
    Node * right = nullptr;
};

Modernes C++

Es ist eine bessere Praxis zu verwenden Smart-Pointer (unique_ptr, shared_ptr, etc.), statt Speicherzuweisungen durch ‘new’:

#include <string>
#include <memory> // For 'std::unique_ptr' 

class Node {
public:
    std::string cargo;
    std::unique_ptr<Node> left;
    std::unique_ptr<Node> right;
};

int main()
{
    auto bt = std::make_unique<Node>();

    (*bt).cargo = "Coffee";
    (*bt).left = std::make_unique<Node>();
}

990210cookie-checkKann eine C++-Klasse sich selbst als Mitglied aufnehmen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy