Da std::listund std::vectorexist, gibt es einen Grund traditionellen C - Arrays in C ++ zu verwenden, oder sollten sie vermieden werden, wie malloc?
Da std::listund std::vectorexist, gibt es einen Grund traditionellen C - Arrays in C ++ zu verwenden, oder sollten sie vermieden werden, wie malloc?
Antworten:
In C ++ 11, wo std::arrayverfügbar, lautet die Antwort "Ja, Arrays sollten vermieden werden". Vor C ++ 11 müssen Sie möglicherweise C-Arrays verwenden, um Arrays im automatischen Speicher (dh auf dem Stapel) zuzuweisen.
Auf jeden Fall, obwohl mit std::arrayin C ++ 11, praktisch nur für statische Daten. Arrays im C-Stil haben drei wichtige Vorteile gegenüber
std::vector:
Sie erfordern keine dynamische Zuordnung. Aus diesem Grund sind Arrays im C-Stil vorzuziehen, wenn Sie wahrscheinlich viele sehr kleine Arrays haben. Sagen Sie so etwas wie einen n-dimensionalen Punkt:
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
Normalerweise könnte man sich einen dimssehr kleinen (2 oder 3),
Teinen eingebauten Typ ( double) vorstellen , bei dem Sie möglicherweise
std::vector<Point>Millionen von Elementen haben. Sie wollen definitiv nicht Millionen von dynamischen Zuordnungen von 3 Doppel.
Die statische Initialisierung unterstützen. Dies ist nur ein Problem für statische Daten, bei denen Folgendes der Fall ist:
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
Dies ist häufig der Verwendung eines Vektors (und std::string) vorzuziehen , da alle Initialisierungsprobleme in der Reihenfolge vermieden werden. Die Daten werden vorinstalliert, bevor ein tatsächlicher Code ausgeführt werden kann.
In Bezug auf das Obige kann der Compiler schließlich die tatsächliche Größe des Arrays aus den Initialisierern berechnen. Sie müssen sie nicht zählen.
Wenn Sie Zugriff auf C ++ 11 haben, werden std::arraydie ersten beiden Probleme gelöst und sollten im ersten Fall definitiv gegenüber Arrays im C-Stil verwendet werden. Der dritte Punkt wird jedoch nicht angesprochen, und wenn das Compiler das Array entsprechend der Anzahl der Initialisierer dimensioniert, ist dies immer noch ein triftiger Grund, Arrays im C-Stil zu bevorzugen.
int i[] = { 1, 2, 3 };arbeitet weiter mit int i[] = { 1, 2, 3, 4 };. array<int, 3>muss manuell geändert werden auf array<int, 4>.
make_arrayFunktion wie make_pairusw. verwendet wird. Hutspitze zu @R. Martinho Fernandes .
std::arrayin C ++ 11 [sie sollten] praktisch nur für statische Daten verwendet werden".
Sagen Sie niemals "nie", aber ich würde zustimmen, dass ihre Rolle durch echte Datenstrukturen von STL stark eingeschränkt wird.
Ich würde auch sagen, dass die Kapselung in Objekten die Auswirkungen solcher Entscheidungen minimieren sollte. Wenn das Array ein privates Datenelement ist, können Sie es ein- oder austauschen, ohne die Clients Ihrer Klasse zu beeinträchtigen.
Ich habe an sicherheitskritischen Systemen gearbeitet, bei denen Sie die dynamische Speicherzuordnung nicht verwenden können. Der Speicher muss immer auf dem Stapel sein. Daher würden Sie in diesem Fall Arrays verwenden, da die Größe zur Kompilierungszeit festgelegt ist.
std::array<T>auf die Stapel verteilt und hat im Grunde keinen Overhead auf einem Raw-Array.
arrayin c++bietet Ihnen eine schnelle Alternative mit fester Größe von dynamischer Größe std::vectorund std::list. std :: array ist eine der Ergänzungen in c++11. Es bietet den Vorteil von Standardcontainern und bietet dennoch die Aggregattypsemantik von Arrays im C-Stil.
Also c++11würde ich in std::array, wo es erforderlich ist, sicherlich über Vektor verwenden. Aber ich würde ein Array im C-Stil vermeiden C++03.
Meistens, nein , ich kann mir keinen Grund vorstellen, Raw-Arrays beispielsweise zu verwenden vectors. Wenn der Code neu ist .
Möglicherweise müssen Sie auf die Verwendung von Arrays zurückgreifen, wenn Ihre Bibliotheken mit Code kompatibel sein müssen, der Arrays und Rohzeiger erwartet.
vector.data()in C ++ 11 oder &vector.front()früher.
Ich weiß, dass viele Leute auf std :: array für die Zuweisung von Arrays auf dem Stapel und std :: vector für den Heap hinweisen. Aber keiner scheint die nicht native Ausrichtung zu unterstützen. Wenn Sie einen numerischen Code verwenden, für den Sie SSE- oder VPX-Anweisungen verwenden möchten (daher eine Ausrichtung von 128 bzw. 256 Byte erforderlich ist), scheinen C-Arrays immer noch die beste Wahl zu sein.
Ich würde sagen, Arrays sind immer noch nützlich, wenn Sie eine kleine statische Datenmenge speichern, warum nicht.
Der einzige Vorteil eines Arrays (natürlich in etwas eingeschlossen, das bei Bedarf automatisch seine Freigabe verwaltet) gegenüber dem, an das std::vectorich denken kann, ist, dass vectores den Besitz seiner Daten nicht weitergeben kann, es sei denn, Ihr Compiler unterstützt C ++ 11 und Verschiebungskonstruktoren.
swap.
Arrays im C-Stil sind eine grundlegende Datenstruktur, daher wird es Fälle geben, in denen es besser ist, sie zu verwenden. Verwenden Sie für den allgemeinen Fall jedoch die erweiterten Datenstrukturen, die die Ecken der zugrunde liegenden Daten abrunden. Mit C ++ können Sie einige sehr interessante und nützliche Dinge mit dem Speicher tun, von denen viele mit einfachen Arrays funktionieren.
std::arrays? Beide werden in vielen Fällen zu derselben Assembly kompiliert.
std::arrayhat genau definierte Semantik auf statischen Arrays aufgebaut.
Sie sollten STL-Container intern verwenden, aber Sie sollten keine Zeiger auf solche Container zwischen verschiedenen Modulen übergeben, da Sie sonst in die Hölle der Abhängigkeit geraten. Beispiel:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
ist eine sehr gute Lösung aber nicht
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
Der Grund dafür ist, dass std :: string auf viele verschiedene Arten implementiert werden kann, ein String im C-Stil jedoch immer ein String im C-Stil ist.