Da std::list
und std::vector
exist, gibt es einen Grund traditionellen C - Arrays in C ++ zu verwenden, oder sollten sie vermieden werden, wie malloc
?
Da std::list
und std::vector
exist, gibt es einen Grund traditionellen C - Arrays in C ++ zu verwenden, oder sollten sie vermieden werden, wie malloc
?
Antworten:
In C ++ 11, wo std::array
verfü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::array
in 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 dims
sehr kleinen (2 oder 3),
T
einen 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::array
die 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_array
Funktion wie make_pair
usw. verwendet wird. Hutspitze zu @R. Martinho Fernandes .
std::array
in 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.
array
in c++
bietet Ihnen eine schnelle Alternative mit fester Größe von dynamischer Größe std::vector
und 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++11
wü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::vector
ich denken kann, ist, dass vector
es 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::array
s? Beide werden in vielen Fällen zu derselben Assembly kompiliert.
std::array
hat 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.