2016-05-06 20 views
1

Wenn ich eine Klasse wie:Filterung dynamisch eine Liste von Objekten C++

class Car { 
    string name; 
    int age; 
    string manufacturer; 
} 

und ich zeige eine Liste von Autos, mit einem Filter Drop-Down-Namen enthält, Alter, Hersteller. Wie kann ich die jeweilige Immobilie am Auto vergleichen?

Ich könnte eine switch-Anweisung verwenden, aber dies würde unübersichtlich werden, wenn es viele Felder gäbe.

In JS oder Objective-C (mit KVC) können Sie dynamisch auf die Eigenschaften eines Objekts zugreifen, also wäre dies einfach.

Speziell frage ich, was ist das entsprechende Muster in C++ für den Zugriff auf eine Variable oder Member-Funktion, die Sie nicht zur Kompilierzeit wissen, weil es zur Laufzeit vom Benutzer zur Verfügung gestellt wird.

+0

In welchem ​​Sinne möchten Sie Eigenschaften vergleichen? Ist es in Ordnung, wenn sie immer als Strings dargestellt werden? –

+0

Fragen Sie, ob es eine Möglichkeit gibt, (a) die Eigenschaften des Objekts zu bestimmen und (b) darauf zuzugreifen, damit Sie zwei Objekte vergleichen können? – Caribou

+0

Nun wäre es schön, in der Lage zu sein, die Eigenschaften des Objekts zu bestimmen, aber hauptsächlich ist es der Zugriff auf sie zu vergleichen, die ich nicht denken kann (das ist nicht in einer anderen Sprache) –

Antwort

2

Normalerweise würden Sie std::map<> verwenden, um die Eigenschaften und nicht einzelne Datenelemente zu speichern.

Dies hat den zusätzlichen Vorteil, dass Eigenschaften zur Laufzeit erstellt werden können, sodass ein gesamtes Datenmodell dynamisch und datengesteuert sein kann.

+0

Die Verwendung einer Karte wird den gespeicherten Typ reparieren, es sei denn, Sie verwenden etwas wie boost :: any. und ich würde nicht immer diesen Weg wählen. – Caribou

+0

Yup ich dachte darüber nach, aber die Eigenschaften sind Mischungen von Saiten, Ints, Dates, etc. wie Caribou sagte. –

1

Es gibt kein gleichwertiges Muster in der Sprache: Im Gegensatz zu JS, Objective-C und anderen Sprachen mit schwergewichtigen Metadaten hat C++ nur eine begrenzte Menge an Laufzeitinformationen für Ihren Code zur Verfügung und es wäre nicht hilfreich Vervollständige deine Aufgabe.

Es bedeutet jedoch nicht, dass es keine Möglichkeit gibt, eigene Metadaten zu erstellen. Sie können eine Funktion erstellen, die einen Zeichenfolgenwert mit einem Feld eines Objekts vergleicht, eine Zuordnung dieser Funktionen zu den entsprechenden Feldern vornimmt und die Funktionen aus Ihrer Zuordnung verwendet, um wie folgt auf die Felder zuzugreifen:

Sie können diese Karten verwenden, wie folgt:

auto cars = vector<Car> { 
    {"Impala", 10, "Chevrolet"} 
, {"Focus", 3, "Ford"} 
, {"Jetta", 3, "VW"} 
}; 
string fieldNameEq, eqCmp; 
cin >> fieldNameEq >> eqCmp; 
cout << "==== Cars matching " << fieldNameEq << "==" << eqCmp << ":" << endl; 
for (auto &c : cars) { 
    if (carFieldEq[fieldNameEq](c, eqCmp)) { 
     cout << c.name << " " << c.age << " " << c.manufacturer << endl; 
    } 
} 
string fieldNameLess, lessCmp; 
cin >> fieldNameLess >> lessCmp; 
cout << "==== Cars matching " << fieldNameLess << "<" << lessCmp << ":" << endl; 
for (auto &c : cars) { 
    if (carFieldLess[fieldNameLess](c, lessCmp)) { 
     cout << c.name << " " << c.age << " " << c.manufacturer << endl; 
    } 
} 

Demo.

Beachten Sie, dass carFieldEq und carFieldLess eine beliebige Zeichenfolge nehmen, die nicht unbedingt den tatsächlichen Namen des Feldes übereinstimmen kann.

+0

Das würde für die Gleichstellung funktionieren, aber Sie konnten nicht alle Autos mit 'Alter <10' –

+0

@ Jonathan filtern. Dies ist nur eine Demo, die Ihnen zeigt, wie Sie mit dem Erstellen eigener Metadaten beginnen können. Sie können eine ähnliche Zuordnung für Funktionen erstellen, die ein Auto und einen ganzzahligen Wert annehmen, und "true" oder "false" zurückgeben, je nachdem, ob das entsprechende Feld kleiner oder nicht kleiner als der angegebene Wert ist. – dasblinkenlight

+0

Ich habe nicht viel Zeit oder ich schreibe die Antwort (: P Entschuldigung) aber wenn Sie anstatt Strings ein Objekt (Variante wie boost :: any) oder möglicherweise Funktoren, die die Werte träge greifen, so dass sie nicht gespeichert werden zweimal könnte es den erforderlichen Funktionsumfang geben – Caribou

Verwandte Themen