Wenn Sie in einer Position sind, in der vector<int>
sogar eine Möglichkeit ist, möchten Sie wahrscheinlich damit gehen, außer in extremen und seltenen Fällen.Und selbst dann könnte ein benutzerdefinierter Typ anstelle von unique_ptr<int[]>
die beste Antwort sein.
Also was zum Teufel ist unique_ptr<int[]>
gut für? :-)
unique_ptr<T[]>
wirklich glänzt in zwei Fällen:
1.
Sie benötigen einen malloc/free Ressource von einer Legacy-Funktion zu handhaben und Sie würden es in einer modernen Ausnahme sichere Art zu tun:
void
foo()
{
std::unique_ptr<char[], void(*)(void*)> p(strdup("some text"), std::free);
for (unsigned i = 0; p[i]; ++i)
std::cout << p[i];
std::cout << '\n';
}
2.
Sie hat Bedarf vorübergehend eine neue [] Ressource zu sichern, bevor es auf einem anderen Inhaber übertragen:
class X
{
int* data_;
std::string name_;
static void validate(const std::string& nm);
public:
~X() {delete [] data_;}
X(int* data, const std::string& name_of_data)
: data_(nullptr),
name_()
{
std::unique_ptr<int[]> hold(data); // noexcept
name_ = name_of_data; // might throw
validate(name_); // might throw
data_ = hold.release(); // noexcept
}
};
Im obigen Szenario besitzt X
den übergebenen Zeiger, unabhängig davon, ob der Konstruktor erfolgreich ist oder nicht. Dieses spezielle Beispiel setzt einen noexcept
Standardkonstruktor für std::string
voraus, der nicht vorgeschrieben ist. Jedoch:
- Dieser Punkt ist verallgemeinerbar für Umstände, die
std::string
nicht betreffen.
- Ein
std::string
Standardkonstruktor, der wirft, ist lahm.
Warum nicht ein std :: array? – Bart
@Bart Er muss den einmal zugewiesenen Speicher nicht vergrößern, das bedeutet nicht, dass er die Größe zur Kompilierzeit kennt. – Praetorian
@Bart Ich habe die Frage aktualisiert, um davon auszugehen, dass die Größe des Puffers zur Kompilierzeit nicht bekannt ist. – huitlarc