Ich spiele herum und schreibe meine eigene Heap-Klasse. Für meine Template-Heap-Klasse müssen die Operatoren '> und' < 'für den Vorlagentyp definiert sein.C++ mit shared_ptr, aber die relationalen Operatoren meines Objekts aufgerufen?
Alles schien gut zu funktionieren, wenn eine Instanz einer Beispielklasse, die ich schrieb, verwendet wurde (und funktionierte auch gut auf int). Da es jedoch so viele Instanzen gibt, wie Klasseninstanzen von verschiedenen Knoten im Heap wechseln, entschied ich mich zu sehen, was passiert ist, als ich einen Heap von shared_ptr meiner Klasse erstellt habe. Während ich sah, dass die Anzahl der erstellten Instanzen weit nach unten ging, funktionierte der Heap nicht korrekt, da der Smart-Zeiger '>' und '<' aufgerufen wird, was ich denke, vergleicht nur intelligente Zeigerreferenzen. Eine Lösung, die mir in den Sinn kommt, ist die Berücksichtigung eines Vergleichstyps, genauso wie viele der STL-Typen, so dass ich meinen eigenen Vergleichstyp in die Heap-Klasse einbringen kann, die das shared_ptr dereferenziert und die Operation aufruft der zugrunde liegende Typ.
Einige Dokumente, die ich auf dem shared_ptr gelesen habe, sagten, dass sie den relationalen Operator (nämlich <) implementieren, so dass sie als Schlüssel in assoziativen Containern verwendet werden könnten. Ich versuche darüber nachzudenken, wann ich das shared_ptr als Schlüssel verwenden möchte, anstatt einen eigenen Schlüssel zu haben.
Haufen meiner Probe Art, die gut zu funktionieren scheint:
heap<foo> foo_heap(heap_type::max);
for (unsigned int i = 0; i < 10; ++i)
{
std::string s = "string ";
s += ('0' + i);
foo f(i, s);
foo_heap.push(f);
}
cout << "root: " << foo_heap.top() << endl;
meine Probe-Klasse in einer Shared_ptr Einwickeln, die zB nicht funktioniert. Heap Constraint nicht in Bezug auf das, was ich zu erreichen versuche erfüllt.
heap<shared_ptr<foo>> foo_heap_smart(heap_type::max);
for (unsigned int i = 0; i < 10; ++i)
{
std::string s = "string ";
s += ('0' + i);
shared_ptr<foo> f(new foo(i, s));
foo_heap_smart.push(f);
}
cout << "root: " << *(foo_heap_smart.top()) << endl;
meine Probe foo Klasse:
class foo
{
public:
foo(int value, std::string s) : _value(value), _s(s)
{
std::cout << "foo::foo()" << std::endl;
}
foo(const foo& f) : _value(f._value), _s(f._s)
{
std::cout << "foo::foo(const foo& f)" << std::endl;
}
~foo()
{
std::cout << "foo::~foo()" << std::endl;
}
virtual void operator=(const foo& f)
{
std::cout << "foo::operator=()" << std::endl;
this->_value = f._value;
this->_s = f._s;
}
virtual bool operator<(const foo& right)
{
return this->_value < right._value;
}
virtual bool operator>(const foo& right)
{
return this->_value > right._value;
}
void print(ostream& stm) const
{
stm << "value: " << this->_value << ", s: " << this->_s;
}
private:
int _value;
std::string _s;
};
Also gehe ich davon aus, dass viele in ein ähnliches Problem ausgeführt haben. Ich frage mich nur, was die vorgeschriebene Lösung ist. Wie ich bereits erwähnt habe, denke ich, dass ich weiß, was erscheint, könnte eine gute Lösung sein, wollte aber überprüfen, wie es scheint, dass der intelligente Zeiger wegen ihrer Implementierung der relationalen Operatoren viele Probleme verursachen könnte.
Danke, Nick
Die vorgeschriebene Lösung besteht darin, eine eigene Version des Vergleichsoperators bereitzustellen, wenn die Standardversion nicht Ihren Anforderungen entspricht. Ein besseres Design für Ihre "Heap" -Klasse wäre auch ein Comparator-Typ, der standardmäßig auf "std :: less" gesetzt werden kann. – Arunmu
Wenn Sie sich Sorgen machen, dass zu viele Kopien erstellt werden, sollten Sie mehr über move semantics lernen springt direkt zu 'std :: shared_ptr'. –
@miles, würde ich gerne über Umzug Semantik lernen. Kannst du mich auf einige Dokumente hinweisen?Ich habe mich gefragt, ob es einen speziellen Swap gibt, den ich verwenden könnte, der den Konstruktor/Destruktor umgehen würde. – nickdu