std::unique_ptr
eine gelöschte Copykonstruktor hat, was bedeutet, dass, wenn Sie einen unique_ptr
in Ihrer Klasse Foo
als Datenelement haben, dann müssen Sie Ihre eigene Kopie Konstruktor für Foo
und manuell tief Kopie schreiben, dass Mitglied (auch wenn Der compilergenerierte Kopierkonstruktor wäre für alle anderen Mitglieder in Ordnung.Auto-Klonen unique_ptr
Um in einer polymorphen Weise kopieren zu können, kann das Methodenmuster clone()
verwendet werden. Nehmen wir an, unsere Objekte ein Klon Verfahren wie dieses:
class Base {
virtual std::unique_ptr<Base> clone() = 0;
};
Foo nun wie folgt aussieht:
class Foo {
public:
...
Foo(Foo const& other)
: b(other.b->clone())
, // init 10 more members that could otherwise be auto-copied just fine
// with the automatically generated copy constructor
{}
...
private:
std::unique_ptr<Base> b;
//10 more data members
};
Nun fand ich einen Weg, um Auto-Klon Foo::b
, durch einen Wrapper über unique_ptr
schreiben, die definiert den Kopierkonstruktor und die Zuweisung durch Aufruf von clone
.
template <typename T>
class auto_cloned_unique_ptr
{
private:
std::unique_ptr<T> up;
public:
// copy constructor
auto_cloned_unique_ptr(auto_cloned_unique_ptr<T> const& other)
: up(other.up->clone()) {}
// copy assignment
auto_cloned_unique_ptr<T>& operator =(auto_cloned_unique_ptr<T> const& other)
{
this->up = other.up->clone();
return *this;
}
auto_cloned_unique_ptr(std::unique_ptr<T> _up)
: up(std::move(_up)) {}
// Delegate everything else to unique_ptr
auto_cloned_unique_ptr(auto_cloned_unique_ptr<T>&& other)
: up(std::move(other.up)) {}
auto_cloned_unique_ptr<T>& operator =(auto_cloned_unique_ptr<T>&& other)
{
this->up = std::move(other.up);
return *this;
}
auto operator *() const {return *up;}
auto operator->() const {return up.operator->();}
auto get() -> const {return up.get();}
};
Nun, wenn wir verwenden diese brauchen wir nicht unsere eigenen Kopierkonstruktor zu definieren:
class Foo2 {
public:
...
private:
auto_cloned_unique_ptr<Base> b;
//10 more data members
};
Ist ein solcher Ansatz sehr verpönt (für einen Nicht-Standard-Wrapper über unique_ptr
verwenden) ?
Es gab viele solche Vorschläge. Suchen Sie nach 'value_ptr', um nur einen zu nennen. Im Allgemeinen ist es schwierig zu garantieren, dass dies richtig angewendet wird, und daher fühlt es sich nicht richtig an, in den Standard zu gehören. –
Übrigens, warum nicht "private" von "unique_ptr" erben und Konstruktorvererbung verwenden? – Columbo
* "Ist solch ein Ansatz sehr verpönt" * Ist eine Frage, die besser auf [CodeReview] (http://codereview.stackexchange.com) IMO passt. – dyp