2016-08-01 14 views
0

Ich arbeite an einer Klasse, die den Indexoperator überlädt ([]). Um die Zuweisung eines Elements zu ermöglichen, muss der Operator einen Verweis auf das Element zurückgeben. Beispiel:STL-Überlastvektorzuweisung

In dieser Situation kann der Clientcode die zurückgegebene Referenz verwenden, um einem Element einen Wert zuzuweisen. Ich möchte jedoch eine Möglichkeit haben, die tatsächliche Zuweisung des Elements abzufangen, so dass ich den zugewiesenen Wert verwenden kann, um eine interne Verwaltung durchzuführen. Gibt es eine relativ saubere und einfache Möglichkeit, dies zu tun, oder sollte ich nur einige Accessor-Funktionen erstellen, anstatt Operator Overloading zu verwenden?

+5

Man würde fragen, warum Sie von 'std :: vector' erben. – PaulMcKenzie

+0

Erben Sie nicht von Klassen, die keinen virtuellen Destruktor bereitstellen. Zumindest nicht so lange, wie du wirklich weißt, was du tust! –

+0

Ich habe std :: vector verwendet, um das Beispiel etwas zu vereinfachen. Meine aktuelle Klasse verwendet eine Karte. Was ich versuche zu implementieren, ist ein Zwei-Wege-Mapping. Ich brauche einen effizienten Weg, um den Schlüssel nur mit dem Wert als Nachschlagen zu erhalten, ohne auf eine lineare Suche zurückgreifen zu müssen. Ich plane, einen anderen Vektor/Map zu verwenden, um eine umgekehrte Zuordnung beizubehalten, aber ich kann den zugewiesenen Wert nicht erfassen. An dieser Stelle scheint es, dass es besser wäre, nur einen Getter/Setter zu verwenden, als eine neue Klasse zu definieren, nur um die Zuweisung zu erfassen. Ein weiteres Problem mit dem Wrapping des Werts in einer Klasse wäre, dass es den Wert, aber nicht den Index erfassen würde. –

Antwort

1

AFAIK Der Vektoroperator std :: vector liefert bereits eine Referenz auf das Element (entweder const oder non-const), so dass er erben und überschreiben muss.

Wenn Sie die Zuweisung des Werts abfangen möchten, müssen Sie den Zuweisungsoperator des Werts selbst definieren/überschreiben (dies ist im Vektorindexoperator nicht möglich). Das wird natürlich nicht mit pure int funktionieren, also müsstest du den int in eine Klasse schreiben, die den Zuweisungsoperator liefert und dort kannst du "alles was du willst" machen.

EDIT:

Ok ich sehe, so ist, dann kann es notwendig sein, einige Überschreibungen zu tun. Für die umgekehrte Suche könnte eine der Möglichkeiten darin bestehen, den Wert nicht in der umgekehrten Struktur zu speichern, sondern einen Zeiger darauf (zum ursprünglichen Ort). Die Wertzuweisung in der ursprünglichen Struktur würde dann mit der Zeigerumleitung wiedergegeben werden. Dies würde auch einen benutzerdefinierten Vergleichsoperator an die Reverse-Lookup-Map übergeben müssen, um die Zeiger, aber die Werte nicht zu vergleichen.

Im Allgemeinen könnte es sich auch lohnen, auch boost::multi_index zu überprüfen, was genau das ermöglicht - eine einzelne Struktur mit mehreren Nachschlage-Indizes zu erstellen.

+0

Zur Klarstellung, das "Housekeeping", das ich tun muss, besteht darin, eine Hilfsdatenstruktur zu behalten, die ich verwenden kann, um eine umgekehrte Suche durchzuführen, d. H. Effizient den Index von dem Wert abzurufen, ohne auf eine lineare Suche zurückzugreifen. Wrapping der Wertzuweisung in einer Klasse in gibt mir Zugriff auf den Wert, aber nicht auf den Schlüssel, so dass auch nicht funktioniert. –

1

Es gibt keine Möglichkeit, die Zuweisung einer Ganzzahl abzufangen. Sie können jedoch stattdessen einen Verweis auf einen benutzerdefinierten Typ zurückgeben, dessen Zuweisungsoperator überladen ist. Der benutzerdefinierte Typ kann in int konvertiert werden, sodass er als ein solcher verwendet werden kann.

Dies bedeutet natürlich, dass Sie nicht std::vector<int> erben können, die einen Verweis auf int zurückgibt. Sie sollten es ohnehin vermeiden, öffentlich std::vector zu erben. Ein Benutzer Ihrer Klasse kann das Objekt versehentlich durch eine std::vector<int>* löschen, die undefiniertes Verhalten hätte.