2016-05-13 3 views
0

Ich würde gerne meine Liste std :: Liste je nach Parameter sortieren. Zum Beispiel:Sortieren einer Std :: Liste <myclass*> mit der Verwendung von Myclass :: Operator [] (Int i)

class myclass 
{ 
    string name, surname; 
public: 
    myclass() {} 
    ~myclass() {} 
    string operator[](int i) 
    { 
     switch (i) 
     { 
     case 1: return name; 
     case 2: return surname; 
     } 
    } 
}; 

template <typename T> 
struct compare 
{ 
    int num; 
    indirect_compare() {} 
    indirect_compare(int i) : num(i) {} 
    ~indirect_compare() {} 
    bool operator()(T * lhs, T * rhs) { return (*lhs)[num] < (*rhs)[num]; } 
}; 

list<myclass*> lst; 
int specified_by_user; 
cin >> specified_by_user; 

//later 

lst.sort(compare<myclass>(specified_by_user)); 

Es funktioniert gut für mich, aber ich bin mir nicht sicher, ob es korrekt ist. Als ich eine Nachricht in Konstruktor und Destruktor im Strukturvergleich hinzufügte, sah ich, dass der Konstruktor nur einmal aufgerufen wurde, aber der Destruktor wurde zum Beispiel 9 Mal aufgerufen, und ich habe keine Ideen, warum es passiert ist. Ich habe versucht, dieses Programm zu debuggen, um es zu überprüfen, aber ich konnte den Grund nicht finden.

Vielen Dank für Hilfe im Voraus!

+2

Die anderen Konstrukteuren war wahrscheinlich die Kopie Ctor. Hast du das beobachtet? – Sheph

+0

Compare's ctor und dtor heißt indirect_compare. Wird das Beispiel kompiliert? Befreien Sie sich auch von den Argumenten, wenn es ungültig ist. – Sheph

+0

'nicht sicher, ob es korrekt ist 'sieht für mich richtig aus, es gibt ein paar verschiedene Möglichkeiten, aber deins ist nicht falsch – vu1p3n0x

Antwort

1

Ich würde versuchen, den Schalter vom Operator [] auf das Vergleichsfunktionsobjekt zu verschieben (vielleicht sogar Lambda). Dadurch können Sie Eigenschaften vergleichen, die nicht vom selben Typ sind. (zB wenn Sie ein Mitglied hinzufügen int age;

Auch ich würde eine Liste der Dinge statt einer Liste von Zeigern zu Dingen haben. Sie könnten das 1 Konstruktor und mehrere löscht Problem bekommen, weil Sie nicht vorsichtig genug mit den Zeigern sind .

etwas wie folgt aus:

struct myclass 
{ 
    string name; 
    string surname; 
}; 

template <typename T> 
struct compare 
{ 
    int num; 
    compare() {} 
    compare(int i) : num(i) {} 
    ~compare() {} 
    bool operator()(const T & lhs, const T & rhs) { 
    switch(num) 
    { 
     case 1: return lhs->name < rhs->name; 
     case 2: return lhs->surname < rhs->surname; 
     default: throw std::logic_error(); 
    } 
    } 
}; 

list<myclass> lst; 
+0

Danke für die Antwort! Die Idee ist in Ordnung, aber ich möchte den Namen und Nachnamen der Mitglieder privat erhalten und weil ich mehr Zeichenfolgen in meiner Klasse habe, möchte ich nicht Getter und Setter für jedes Mitglied erstellen. Deshalb habe ich operator [] benutzt. – Ben

0

Ihr Code sieht gut Ihre Lösung ein wenig ungewöhnlich ist, aber wenn es für Sie es im Geiste der Mircea Baja gehen funktioniert würde ich gerne zeigen.! Sie eine alternative Lösung für Ihr Problem, nur zur Inspiration:

if (specified_by_user) // sort by name 
    lst.sort(auto [](auto const & a, auto const & b){ return a.name < b.name; }); 
else // sort by surname 
    lst.sort(auto [](auto const & a, auto const & b){ return a.surname < b.surname; }); 

Zuerst verschieben wir die Entscheidung, nach welchem ​​Feld aus Ihrer Klasse und in den Client-Code sortiert werden soll. Zweitens, statt eine Komparatorstruktur zu definieren, übergeben wir lambdas in lst.sort(), was sehr präzise, ​​inline im Funktionsaufruf selbst definiert werden kann.

Dies bedeutet, dass die Felder Name und Nachname öffentlich sind (damit die Lambdas auf sie zugreifen können). Wenn Sie möchten, dass sie privat halten, können Sie Getter Ihrer Klasse hinzufügen:

string const & get_name() const { return name; } 

und die Lambda-Ausdrücke leicht ändern:

auto [](auto const & a, auto const & b){ return a.get_name() < b.get_name(); } 
+0

Es ist großartig, aber ich möchte Mitglieder Namen und Nachnamen privat zu bewahren und weil ich mehr Zeichenfolgen in meiner Klasse habe ich möchte nicht Getter und Setter für jedes Mitglied erstellen (vor allem, dass ich sie nur in diesem Fall verwenden würde). Die Vergleiche funktionieren auf die gleiche Weise, also habe ich versucht, meinen Code zu verkürzen. Aus diesem Grund habe ich operator [] benutzt. – Ben

Verwandte Themen