O zamandan beri std::list
ve std::vector
var, C ++ 'da geleneksel C dizilerini kullanmak için bir neden var mı, yoksa aynen olduğu gibi kaçınılmalı malloc
mı?
O zamandan beri std::list
ve std::vector
var, C ++ 'da geleneksel C dizilerini kullanmak için bir neden var mı, yoksa aynen olduğu gibi kaçınılmalı malloc
mı?
Yanıtlar:
Kullanılabildiği C ++ 11'de std::array
yanıt "evet, dizilerden kaçınılmalıdır". C ++ 11'den önce, dizileri otomatik depolamada (yani yığın üzerinde) tahsis etmek için C dizilerini kullanmanız gerekebilir.
Kesinlikle, std::array
C ++ 11'de olmasına rağmen , pratik olarak sadece statik veriler için. C tarzı dizilerin üç önemli avantajı vardır
std::vector
:
Dinamik ayırma gerektirmezler. Bu nedenle, çok sayıda çok küçük diziye sahip olabileceğiniz yerlerde C tarzı diziler tercih edilmelidir. N boyutlu nokta gibi bir şey söyleyin:
template <typename T, int dims>
class Point
{
T myData[dims];
// ...
};
Tipik olarak, dims
çok küçük (2 veya 3), T
yerleşik bir tür ( double
) ve
std::vector<Point>
milyonlarca öğeyle sonuçlanabileceğiniz bir hayal edilebilir
. Kesinlikle 3 çiftli milyonlarca dinamik ayırma istemezsiniz.
Statik başlatma desteği. Bu yalnızca aşağıdaki gibi bir şeyin olduğu statik veriler için bir sorundur:
struct Data { int i; char const* s; };
Data const ourData[] =
{
{ 1, "one" },
{ 2, "two" },
// ...
};
Bu, tüm başlatma sorunlarını std::string
ortadan kaldırdığı için genellikle bir vektör (ve ) kullanmaya tercih edilir ; herhangi bir gerçek kod çalıştırılmadan önce veriler önceden yüklenir.
Son olarak, yukarıdakilerle ilgili olarak, derleyici, başlatıcılardan dizinin gerçek boyutunu hesaplayabilir. Bunları saymanıza gerek yok.
C ++ 11'e erişiminiz varsa std::array
, ilk iki sorunu çözer ve kesinlikle ilk durumda C tarzı diziler yerine kullanılmalıdır. Bununla birlikte, üçüncüyü ele almaz ve derleyici boyutunun başlatıcı sayısına göre diziye sahip olması, yine de C tarzı dizileri tercih etmek için geçerli bir nedendir.
int i[] = { 1, 2, 3 };
ile çalışmaya devam ediyor int i[] = { 1, 2, 3, 4 };
. array<int, 3>
olarak manuel olarak değiştirilmesi gerekiyor array<int, 4>
.
make_array
fonksiyonu benzer make_pair
vb Şapka-ucu @R. Martinho Fernandes .
std::array
C ++ 11'de olmasına rağmen, pratik olarak yalnızca statik veriler için [kullanılmalıdır]".
Asla "asla" deme, ancak rollerinin STL'nin gerçek veri yapıları tarafından büyük ölçüde azaldığını kabul ediyorum.
Nesnelerin içindeki kapsüllemenin bu gibi seçimlerin etkisini en aza indirmesi gerektiğini de söyleyebilirim. Dizi bir özel veri üyesiyse, sınıfınızın istemcilerini etkilemeden diziyi içeri veya dışarı takas edebilirsiniz.
Dinamik bellek ayırmayı kullanamadığınız güvenlik açısından kritik sistemler üzerinde çalıştım. Hafıza her zaman yığında olmalıdır. Bu nedenle, bu durumda, boyut derleme zamanında sabit olduğundan dizileri kullanırsınız.
std::array<T>
yığınlara ayırır ve temelde ham dizide ek yük yoktur.
array
içinde c++
sen dinamiğinin hızlı alternatif Sabit ölçülere verir büyüklükte std::vector
ve std::list
. std :: array , içindeki eklemelerden biridir c++11
. Std kapsayıcılarının yararını sağlarken, yine de C tarzı dizilerin toplu tür anlambilimini sağlar.
Bu yüzden , gerektiği yerde c++11
kesinlikle std::array
vektör üzerinden kullanırdım. Ama C tarzı diziden kaçınırdım C++03
.
Çoğu zaman, hayır , mesela ham dizileri kullanmak için bir neden düşünemiyorum vectors
. Kod yeniyse .
Kitaplıklarınızın diziler ve ham işaretçiler bekleyen kodlarla uyumlu olması gerekiyorsa dizileri kullanmaya başvurmanız gerekebilir.
vector.data()
C ++ 11 veya &vector.front()
öncesinde.
Bir çok insanın yığındaki dizileri ayırmak için std :: array'i ve yığın için std :: vector'u işaret ettiğini biliyorum. Ancak hiçbiri yerel olmayan uyumu desteklemiyor gibi görünüyor. SSE veya VPX talimatlarını kullanmak istediğiniz herhangi bir tür sayısal kod yapıyorsanız (dolayısıyla sırasıyla 128 veya 256 bayt hizalama gerektirir), C dizileri yine de en iyi seçeneğiniz gibi görünecektir.
Dizilerin hala yararlı olduğunu söyleyebilirim, eğer az miktarda statik veri depoluyorsanız neden olmasın.
Üzerinde (otomatik olarak serbest bırakılmasına zaman ihtiyaç yönetecek ders şeye sarılmış arasında) bir dizinin tek avantajı std::vector
tek düşündüğüm yani vector
, onun verilerin sahipliğini geçemez sizin derleyici desteklerin sürece C ++ 11 ve hareket kurucular.
swap
.
C tarzı diziler temel bir veri yapısıdır, bu nedenle onu kullanmanın daha iyi olduğu durumlar olacaktır. Ancak genel durum için, temeldeki verilerin köşelerini yuvarlayan daha gelişmiş veri yapılarını kullanın. C ++, çoğu basit dizilerle çalışan bellekle çok ilginç ve yararlı şeyler yapmanızı sağlar.
std::array
s'den nasıl daha temeldir? Her ikisi de birçok durumda aynı derlemede derlenecektir.
std::array
statik dizilerin üzerine inşa edilmiş kesin olarak tanımlanmış semantiğe sahiptir.
STL kaplarını dahili olarak kullanmalısınız, ancak işaretçileri farklı modüller arasında bu tür kaplara geçirmemelisiniz, yoksa bağımlılık cehennemine girersiniz. Misal:
std::string foo;
// fill foo with stuff
myExternalOutputProc(foo.c_str());
çok iyi bir çözüm ama değil
std::string foo;
// fill foo with stuff
myExternalOutputProc(&foo);
Bunun nedeni, std :: string'in birçok farklı yolla gerçeklenebilmesidir, ancak c-style string her zaman c-style string'tir.