Ich habe noch kein pimpl-Beispiel gesehen, das sowohl unique_ptr als auch move-semantics verwendet.
Ich möchte eine CHelper-Klasse zu STL-abgeleiteten Containern hinzufügen und pimpl verwenden, um zu verbergen, was CHelper tut.
Sieht das richtig aus?
'
Da das einzige Mitglied von CHelper
ein unique_ptr
ist und die Standardimplementierung von copy die Kopie der Basen und der Mitglieder aufruft, ruft die Standardimplementierung für move auf Wenn Sie move der Basen und Mitglieder verschieben, müssen Sie die CHelper
ctors und assigns nicht überschreiben. Lass den Standard einfach seine Arbeit machen. Sie rufen einfach den entsprechenden unique_ptr-Move-Konstruktor und -Operator auf.
Über das Zusammenstellen von CHelper
und a set<...>
zu einem CDerived ... das ist kein "kanonisches Design" ( set
ist keine OOP-Klasse ..., und CHelper ist es auch nicht) aber kann funktionieren, wenn Sie richtig verwendet werden (versuchen Sie nicht, CDerived
einem CHelper*
ad call delete darauf zuzuweisen, oder Sie werden in Tränen enden). Es gibt einfach nicht genug Informationen, um zu verstehen, was sie vorhaben.
Wenn das Problem ist "Ich möchte, dass Chelper auch kopieren kann", dann sollten Sie wahrscheinlich besser sein
einem Idiom wie folgt folgen ( #include
und using namespace
auseinander ...)
Natürlich können Sie Deklarationen und Implementierungen nach Belieben trennen.
EDIT folgenden John Balcom Kommentare.
Ja, natürlich ändert sich der Code, aber nicht in seiner Substanz.
Sie können nur struct impl;
in CHelper
weiterleiten (so dass unique_ptr eine Bedeutung hat), dann deklarieren
struct CHelper::impl
woanders (möglicherweise in der CPP-Datei, wo alle CHelper-Implementierungen ausgeführt werden).
Hier ist nur zu beachten, dass in der CPP-Datei CHelper :: impl sowohl Konstruktor als auch Destruktor definiert sein müssen, um eine kohärente unique_ptr-Instantiierung (die den impl-Destruktor aufrufen muss) innerhalb der CPP-Datei zu haben. Andernfalls besteht bei einigen Compilern das Risiko, dass in allen Dateien, die die CHelper-Deklaration enthalten, ein Fehler "unvollständige Typverwendung" auftritt.
Über den zweiten Punkt (abgeleitet von std::set
) ist dies ein umstrittener Aspekt der C ++ Programmierung.
Aus Gründen, die für C ++ selbst nicht relevant sind, aber mit der objektorientierten Programmierschule, bedeutet "inhertance" "ist ein" und "ist ein" bedeutet "Objekt-Substitution möglich" .
Da das Löschen eines Objekts über einen Basiszeiger UB ist, wenn das Basis-dtor nicht virtuell ist, also die Objektsoubstitution UB macht, verweigern die OOP-Schule als Dogma die Vererbung der Klasse, die kein virtuelles dtor hat, und wegen des Weges Sie waren erzogen worden, als sie anfingen zu programmieren, sie fangen an, ihre Flamme auf dich zu spucken, wenn du das tust.
Für mich ist das kein Problem in Ihrem Design, aber ihr Fehler zu verstehen, dass C ++ Vererbung nicht " ist ein " bedeutet, sondern " ist wie " und tut es auch nicht implizieren Objektersetzung (für mich ist es ihre Schuld zu denken, jede C ++ Klasse ist ein OOP-Objekt, nicht mit einem Werkzeug, um etwas Nützliches für Sie zu tun, schauen Sie einfach hier oder hier , wenn Sie mehr Klarheit über meine Position haben wollen: Objektersetzung in C ++ ist nicht für "Objekt", sondern Methode für Methode, da jede Methode virtuell oder nicht unabhängig voneinander sein kann. Das heißt, vielleicht musst du mit diesen Leuten arbeiten, also ... bewerte Vor-und Nachteile, indem du ihnen bei der Ausübung ihrer eigenen Lieblingsreligion nicht folgst.
Tags und Links c++ c++11 unique-ptr