2016-09-20 2 views
2

Wir drei STL und STL-geerbt erstellen Datentypen zur Verwendung in einem Cluster-Algorithmus:remove() Bearbeitung von STL Multi-Vererbung

typedef std::vector<double>Point; // A list of parameters (a single observation) 

struct Cluster : std::list<Point> { // A list of Points 
    // Additional member variables 
    Point centroid; 
    bool centroid_valid; 
    bool sort_valid; 
    // Cluster functions omitted 
}; 

struct Universe : std::list<Cluster> { // A list of Clusters 
    // No member variables 
    // Universe functions omitted 
}; 

Dies ist ein Versuch, in vollem Umfang die STL zu verwenden, so dass nichts new ist würde existieren. Die Sorge ist, die mit der Art von nachrangigen STL-Funktionalität zu tun, speziell:

Wenn wir remove() ein Cluster Element aus einer Universe Liste, würden die STL behandeln nicht nur das Löschen (und Speicherverwaltung) alles Point s in der Cluster entfernt werden, sondern auch die Löschbehandlung aller Mitgliedsvariablen?

Hinweis: Alle Elementfunktionen sind relativ einfach, ohne statische Operationen.

+3

Ja. Aber es ist eine schlechte Idee, Standardcontainer zu erben. Ein Universum * hat * eine Anzahl von Clustern, aber das ist nicht alles, was es * ist. –

+1

Diese Art von Standardcontainern soll nicht wirklich vererbt werden. –

+1

Hier ist ein weiterer Grund, nicht zu erben: Nehmen wir an, Sie müssen in Zukunft den Speicher eines Clusters ändern, um beispielsweise eine Eigen-Matrix zu sein, damit Operationen über die gesamte Matrix zusammengefasst und optimiert werden können. Sie wollen nicht, dass Ihre Schnittstelle in die STL-Schnittstelle gezwungen wird, sondern stattdessen durch Ihren Datentyp: 'Cluster :: AddPoint()' zum Beispiel. – Peter

Antwort

3

Wenn wir() ein Cluster-Element aus einer Universum-Liste zu entfernen, würde das STL Griff nicht nur das Löschen (und Speicherverwaltung) alle Punkte im Cluster entfernt werden, sondern auch die Streichung -handling von alle Mitgliedsvariablen?

Ja wird es, weil es auf Cluster-Objekte funktioniert und das Entfernen alle Felder entfernt. Die Vererbung von Standardcontainern wird jedoch als schlechte Methode angesehen, da sie keinen virtuellen Destruktor haben. Es ist besser, die Liste der Punkte in einem Cluster als Eigenschaft zu speichern.

+0

Danke - können Sie erweitern, was Sie meinen, "Es ist besser, Liste der Punkte in einem Cluster als eine Eigenschaft zu speichern?" – Miller

+1

@Miller bedeutet, dass es besser ist zu aggregieren als zu erben. – Slava

1

falsch:

typedef std::vector<double>Point; // A list of parameters (a single observation) 

struct Cluster : std::list<Point> { // A list of Points 
    // Additional member variables 
    Point centroid; 
    bool centroid_valid; 
    bool sort_valid; 
    // Cluster functions omitted 
}; 

rechts:

typedef std::vector<double>Point; // A list of parameters (a single observation) 

struct Cluster { // A list of Points 

    std::list<Point> points; 

    // Additional member variables 
    Point centroid; 
    bool centroid_valid; 
    bool sort_valid; 
    // Cluster functions omitted 
}; 

Wenn Sie von einer Klasse erben, Sie sind von Natur aus zu gewährleisten, dass alle seine Mitgliederfunktionen sanely verhält, wenn gegen Ihre Klasse.

Das Problem für Sie ist, dass die 'zusätzlichen Member-Variablen' Beobachtungen der Punkte zwischengespeichert werden. Wenn Sie erase oder insert einen Punkt, diese zwischengespeicherten Beobachtungen werden nicht synchron sein, und daher falsch.

Wenn Cluster dieselbe Schnittstelle wie std :: list haben soll, müssen Sie diese Schnittstelle implementieren, in das Element points aufrufen und die zwischengespeicherten Beobachtungen aktualisieren (oder als ungültig markieren).