Dizi ile unique_ptr için herhangi bir kullanım var mı?


238

std::unique_ptr dizileri destekler, örneğin:

std::unique_ptr<int[]> p(new int[10]);

ama gerekli mi? muhtemelen std::vectorveya kullanmak daha uygundur std::array.

Bu yapı için herhangi bir kullanım buluyor musunuz?


6
Tamlık için, hiç std::shared_ptr<T[]>olmadığına dikkat etmeliyim, ama olmalı ve muhtemelen bir teklif yazmak için rahatsız edilebilecekse C ++ 14'te olacaktır. Bu arada, her zaman vardır boost::shared_array.
Takma ad

13
std::shared_ptr<T []> şimdi c ++ 17'de.
力 力

Bilgisayarda herhangi bir şey yapmanın birden çok yolunu bulabilirsiniz. Bu yapı, özellikle sıcak bir yolda kullanmaktadır, çünkü dizinizi tam olarak nasıl hedefleyeceğinizi biliyorsanız, konteyner işlemlerinin ek yükünü ortadan kaldırır. Ayrıca, bitişik depolama şüphesi olmadan karakter dizileri yapar.
kevr

Yanıtlar:


256

Bazı insanlar std::vector, ayırıcılarla bile kullanma lüksüne sahip değildir . Bazı insanlar dinamik olarak boyutlandırılmış bir diziye ihtiyaç duyarlar std::array. Ve bazı insanlar dizilerini bir dizi döndürdüğü bilinen diğer kodlardan alırlar; ve bu kod bir vectorşey döndürmek için yeniden yazılmayacak .

İzin vererek unique_ptr<T[]>, bu ihtiyaçlara hizmet edersiniz.

Kısacası, ihtiyacınızunique_ptr<T[]> olduğunda kullanırsınız. Alternatifler sizin için işe yaramayacağı zaman. Son çare bir araç.


27
@NoSenseEtAl: "Bazı kişilerin bunu yapmasına izin verilmiyor" un hangi bölümünün sizi atlattığından emin değilim. Bazı projelerin çok özel gereksinimleri vardır ve bunların arasında "kullanamazsınız vector" olabilir. Sen o makul şartlar olup olmadıklarını iddia, ancak onlar inkar edemez var .
Nicol Bolas

21
Birisi kullanmak mümkün olmaz neden dünyada hiçbir sebep yoktur std::vectoronlar kullanabilir eğer std::unique_ptr.
Miles Rout

66
vektörü kullanmamanın bir nedeni: sizeof (std :: vector <char>) == 24; sizeof (std :: unique_ptr <char []>) == 8
Arvid

13
@DanNissenbaum Bu projeler var. Havacılık veya savunma gibi çok sıkı bir şekilde incelenen bazı endüstriler, standart kütüphane sınırlıdır, çünkü yönetim organının düzenlemeleri belirleyen her şeyin doğru olduğunu doğrulamak ve kanıtlamak zordur. Standart kütüphanenin iyi test edildiğini ve sizinle aynı fikirde olduğunu iddia edebilirsiniz, ancak siz ve ben kuralları yerine getirmiyoruz.
Emily L.

16
@DanNissenbaum Ayrıca bazı sabit gerçek zamanlı sistemlerin dinamik bellek ayırmayı kullanmasına izin verilmez, çünkü sistem çağrısının neden olduğu gecikme teorik olarak sınırlandırılmayabilir ve programın gerçek zamanlı davranışını kanıtlayamazsınız. Veya sınır, WCET sınırınızı aşan çok büyük olabilir. Her ne kadar burada uygulanamaz olsalar da, kullanmadıkları için unique_ptrbu tür projeler gerçekten var.
Emily L.

124

Ödünleşmeler vardır ve istediğiniz şeye uyan çözümü seçersiniz. Kafamın üstünden:

Başlangıç ​​boyutu

  • vectorve unique_ptr<T[]>boyutun çalışma zamanında belirtilmesine izin ver
  • array boyutun yalnızca derleme zamanında belirtilmesine izin verir

yeniden boyutlandırma

  • arrayve unique_ptr<T[]>yeniden boyutlandırmaya izin verme
  • vector yapar

Depolama

  • vectorve unique_ptr<T[]>verileri nesnenin dışında (genellikle yığın üzerinde) depolar
  • array verileri doğrudan nesnede saklar

Kopyalama

  • arrayve vectorkopyalamaya izin ver
  • unique_ptr<T[]> kopyalamaya izin vermiyor

Takas / taşı

  • vectorve unique_ptr<T[]>O (1) zaman swapve hareket işlemlerine sahip olmak
  • arrayO (n) zaman swapve hareket işlemine sahiptir, burada n dizideki eleman sayısıdır

İşaretçi / referans / yineleyici geçersiz kılma

  • array işaretçi, referans ve yineleyicilerin nesne canlıyken bile geçersiz kılınmamasını sağlar. swap()
  • unique_ptr<T[]>yineleyicisi yoktur; işaretçiler ve referanslar yalnızca swap()nesne canlıyken geçersiz kılınır . (Takas ettikten sonra, işaretçiler takas ettiğiniz diziyi gösterir, bu yüzden yine de bu anlamda "geçerlidir".)
  • vector herhangi bir yeniden tahsis için işaretçileri, referansları ve yineleyicileri geçersiz kılabilir (ve yeniden tahsisin yalnızca belirli işlemlerde olabileceğine dair bazı garantiler sağlar).

Kavramlar ve algoritmalarla uyumluluk

  • arrayve vectorher ikisi de Konteyner
  • unique_ptr<T[]> bir Konteyner değil

İtiraf etmeliyim ki, bu politika tabanlı tasarımla bazı yeniden düzenleme için bir fırsat gibi görünüyor.


1
İşaretçi geçersiz kılma bağlamında ne demek istediğinizi anladığımdan emin değilim . Bu, nesnelerin kendilerine veya öğelere işaretçilerle mi ilgili? Veya başka bir şey? Bir vektörden almadığınız bir diziden ne tür bir garanti alıyorsunuz?
jogojapan

3
Bir yineleyici, bir işaretçi veya a öğesinin bir referansına sahip olduğunuzu varsayalım vector. Ardından, vectoryeniden tahsisi zorlayacak şekilde boyutunu veya kapasitesini arttırırsınız . Sonra bu yineleyici, işaretçi veya başvuru artık öğesinin bu öğesini göstermez vector. "Geçersiz kılma" ile kastettiğimiz budur. Bu sorun gerçekleşmez array, çünkü "yeniden tahsis" yoktur. Aslında, bununla ilgili bir ayrıntı gördüm ve uygun olması için düzenledim.
Takma isim

1
Tamam, bir dizide yeniden tahsis sonucu veya yeniden tahsis olmadığından geçersiz unique_ptr<T[]>kılınamaz. Ancak elbette, dizi kapsam dışına çıktığında, belirli öğelere işaretçiler yine de geçersiz kılınacaktır.
jogojapan

Evet, nesne artık canlı değilse tüm bahisler kapalıdır.
Takma isim

1
@rubenvb Elbette yapabilirsiniz, ancak döngüler için aralık tabanlı doğrudan kullanamazsınız (diyemezsiniz). Bu arada, normalin aksine T[], boyutun (veya eşdeğer bilgilerin) operator delete[]dizinin öğelerini doğru bir şekilde yok etmek için bir yerde asılı olması gerekir . Programcının buna erişimi olsaydı iyi olurdu.
Takma ad

73

A'yı kullanmanızın bir nedeni , diziyi başlatma değerininunique_ptr çalışma zamanı maliyetini ödemek istememenizdir .

std::vector<char> vec(1000000); // allocates AND value-initializes 1000000 chars

std::unique_ptr<char[]> p(new char[1000000]); // allocates storage for 1000000 chars

std::vectorYapıcı ve std::vector::resize()initialize-değeri olacaktır T- ama neweğer bunu yapmayacağım Tbir POD olduğunu.

Bkz . C ++ 11 ve std :: vector yapıcısında Başlatılmış Değer Nesneleri

vector::reserveBurada alternatif olmadığını unutmayın : std :: vector :: reserve'tan sonra ham işaretçiye erişmek güvenli midir?

Bu bir C programcısı seçebilir aynı sebepten mallocüzerinde calloc.


Ancak bu sebep tek çözüm değildir .
Ruslan

@Ruslan Bağlantılı çözümde dinamik dizinin elemanları hala değer başlatılır, ancak değer başlatma işlemi hiçbir şey yapmaz. Hiçbir kod ile 1000000 kez hiçbir şey uygulanamayacağını fark edemeyen bir optimiser bir kuruşa değer değil, ama bir hiç bu optimizasyon bağımlı olmayı tercih edebilir kabul ediyorum.
Marc van Leeuwen

Yine bir başka olasılık için sağlamaktır std::vectorbir özel ayırıcı olan türleri yapımını önler std::is_trivially_default_constructibleve nesnelerin imha std::is_trivially_destructible(örneğin tip başlatıldı default olmadığı için) olsa kesinlikle bu C ++ standardı ihlal.
Walter

Ayrıca std::unique_ptrbirçok std::vectoruygulamaya aykırı herhangi bir sınırlama kontrolü sağlamaz .
diapir

@diapir Bu uygulama ile ilgili değildir: std::vectorStandart tarafından sınırları kontrol etmek gerekir .at(). Bazı uygulamaların da kontrol edecek hata ayıklama modlarına sahip olduğunu kastediyorsunuz .operator[], ancak iyi, taşınabilir kod yazmak için işe yaramaz olduğunu düşünüyorum.
underscore_d

30

Bir std::vectorsüre etrafta kopyalanabilir unique_ptr<int[]>dizinin benzersiz sahipliğini ifade verir. std::arrayÖte yandan, boyutun derleme zamanında belirlenmesini gerektirir, bu da bazı durumlarda imkansız olabilir.


2
Bir şey sırf edebilirsiniz etrafında kopyalanabilir olması gerektiği anlamına gelmez.
Nicol Bolas

4
@NicolBolas: Anlamıyorum. Birisi unique_ptrbunun yerine neden kullanacağını önlemek isteyebilir shared_ptr. Bir şey mi kaçırıyorum?
Andy Prowl

4
unique_ptrsadece yanlışlıkla kötüye kullanımı önlemekten daha fazlasını yapar. Aynı zamanda daha küçük ve daha düşük ek yük shared_ptr. Mesele şu ki, "yanlış kullanımı" önleyen bir sınıfta anlambilime sahip olmak güzel olsa da, belirli bir türü kullanmanın tek nedeni bu değildir. Ve vectorbir dizi depolama olarak unique_ptr<T[]>, bir boyutu olması gerçeğinden başka bir sebep yoksa , çok daha kullanışlıdır .
Nicol Bolas

3
Bu noktayı açıklığa kavuşturduğumu sanıyordum: Belirli bir türü kullanmanın başka nedenleri de var. Sadece tercih nedeni vardır gibi vectorüzerinde unique_ptr<T[]>yerine söyleyerek, "Bunu kopyalayamazsınız" ve bu nedenle almak mümkün olduğunda unique_ptr<T[]>sen kopyalarını istemiyorum zaman. Birinin yanlış şeyi yapmasını durdurmak, bir sınıf seçmenin en önemli nedeni olmayabilir.
Nicol Bolas

8
std::vectora'dan daha fazla ek yüke sahiptir std::unique_ptr- ~ 1 yerine ~ 3 işaretçi kullanır. std::unique_ptrkopya yapısını engeller, ancak semantik olarak çalıştığınız veriler yalnızca taşınabiliyor ancak kopyalanamıyorsa, classverileri içeren verileri bozar . Geçerli olmayan veriler üzerinde işlem yapmak kap sınıfınızı daha da kötüleştirir ve "sadece kullanmayın" tüm günahları yıkamaz. std::vectorEl ile devre dışı bıraktığınız bir sınıfın her örneğini koymak movebir baş ağrısıdır. std::unique_ptr<std::array>vardır size.
Yakk - Adam Nevraumont

22

Scott Meyers bunu Etkili Modern C ++ ile söylemektedir

Varlığı std::unique_ptrnedeniyle diziler, yalnızca sizin entelektüel ilgi olmalıdır için std::array, std::vector, std::stringneredeyse her zaman çiğ diziler daha iyi veri yapısı seçeneklerdir. Sahip std::unique_ptr<T[]>olduğunuzu varsaydığınız bir yığın dizisine ham bir işaretçi döndüren C-benzeri bir API kullandığınızda ne zaman mantıklı olacağını düşündüğüm tek durum hakkında.

Charles Salvia'nın cevabının yine de alakalı olduğunu düşünüyorum: std::unique_ptr<T[]>derleme zamanında bilinmeyen boş bir dizi başlatmanın tek yolu budur. Scott Meyers'ın bu kullanım motivasyonu hakkında ne söylemesi gerekir std::unique_ptr<T[]>?


4
Birkaç kullanım örneği öngörmemiş gibi görünüyor, yani boyutu sabit olan ancak derleme zamanında bilinmeyen bir tampon ve / veya kopyalara izin vermediğimiz bir tampon. Ayrıca vector stackoverflow.com/a/24852984/2436175'i tercih etmenin olası bir nedeni olarak verimlilik var .
Antonio

17

Bunun aksine std::vectorve std::array, std::unique_ptrbir NULL işaretçisine sahip olabilir.
Bu, bir dizi veya NULL bekleyen C API'leriyle çalışırken kullanışlıdır:

void legacy_func(const int *array_or_null);

void some_func() {    
    std::unique_ptr<int[]> ptr;
    if (some_condition) {
        ptr.reset(new int[10]);
    }

    legacy_func(ptr.get());
}

10

Ben kullandım unique_ptr<char[]>bir oyun motoru kullanılan bir önceden tahsis edilen alanlara bellek havuzları uygulamaktır. Fikir, her karede bellek ayırmak / boşaltmak zorunda kalmadan, çarpışma istekleri sonuçlarını ve parçacık fiziği gibi diğer şeyleri döndürmek için dinamik ayırmalar yerine kullanılan önceden ayrılmış bellek havuzları sağlamaktır. İmha mantığı gerektirmeyen sınırlı yaşam süresine (genellikle bir, 2 veya 3 kare) sahip nesneleri ayırmak için bellek havuzlarına ihtiyaç duyduğunuz bu tür senaryolar için oldukça uygundur.


9

Bazı Windows Win32 API çağrılarında yaygın bir desen bulunabilir , burada kullanımının std::unique_ptr<T[]>kullanışlı olabileceği, örneğin bazı Win32 API'lerini çağırırken bir çıkış arabelleğinin ne kadar büyük olması gerektiğini tam olarak bilmediğinizde (içine bazı veriler yazacaktır) bu tampon):

// Buffer dynamically allocated by the caller, and filled by some Win32 API function.
// (Allocation will be made inside the 'while' loop below.)
std::unique_ptr<BYTE[]> buffer;

// Buffer length, in bytes.
// Initialize with some initial length that you expect to succeed at the first API call.
UINT32 bufferLength = /* ... */;

LONG returnCode = ERROR_INSUFFICIENT_BUFFER;
while (returnCode == ERROR_INSUFFICIENT_BUFFER)
{
    // Allocate buffer of specified length
    buffer.reset( BYTE[bufferLength] );
    //        
    // Or, in C++14, could use make_unique() instead, e.g.
    //
    // buffer = std::make_unique<BYTE[]>(bufferLength);
    //

    //
    // Call some Win32 API.
    //
    // If the size of the buffer (stored in 'bufferLength') is not big enough,
    // the API will return ERROR_INSUFFICIENT_BUFFER, and the required size
    // in the [in, out] parameter 'bufferLength'.
    // In that case, there will be another try in the next loop iteration
    // (with the allocation of a bigger buffer).
    //
    // Else, we'll exit the while loop body, and there will be either a failure
    // different from ERROR_INSUFFICIENT_BUFFER, or the call will be successful
    // and the required information will be available in the buffer.
    //
    returnCode = ::SomeApiCall(inParam1, inParam2, inParam3, 
                               &bufferLength, // size of output buffer
                               buffer.get(),  // output buffer pointer
                               &outParam1, &outParam2);
}

if (Failed(returnCode))
{
    // Handle failure, or throw exception, etc.
    ...
}

// All right!
// Do some processing with the returned information...
...

Sadece std::vector<char>bu durumlarda kullanabilirsiniz .
Arthur Tacca

@ArthurTacca - ... arabellek içindeki her karakteri 0 birer birer başlatan sakıncası yoksa.
TED

9

std::unique_ptr<bool[]>HDF5 kütüphanesinde (verimli ikili veri depolama kütüphanesi, bilimde çok kullanılan) kullanmak zorunda olduğum bir durumla karşılaştım . Bazı derleyiciler (benim durumumda Visual Studio 2015 ), HDF5 gibi bir şey için bir felaket olan sıkıştırmayı sağlarstd::vector<bool> (her baytta 8 bool kullanarak). İle std::vector<bool>, HDF5 bu sıkıştırma nedeniyle sonunda çöp okuyordu.

Tahmin et std::vectorişe yaramadı, kurtarma için orada kim vardı ve ben temiz dinamik bir dizi tahsis gerekiyordu? :-)


9

Özetle: bu, bellek açısından en verimli olanıdır.

A std::string, bir işaretçi, uzunluk ve "kısa dize optimizasyonu" arabelleği ile birlikte gelir. Ama benim durumum, yüz binlerce var olan bir yapıda neredeyse her zaman boş olan bir dize saklamam gerekiyor. C'de sadece kullanırdım char *ve çoğu zaman boş olur. C ++ için de çalışır, ancak a char *yok edici yoktur ve kendini silmeyi bilmez. Buna karşılık, a std::unique_ptr<char[]>kapsam dışına çıktığında kendini siler. Bir boş std::string32 bayt alır, ancak bir boş std::unique_ptr<char[]>8 bayt, yani tam olarak işaretçisinin boyutu alır.

En büyük dezavantajı, ipin uzunluğunu her bilmek istediğimde strlen, onu çağırmak zorundayım.


3

Aygıt yerine bellek ayırdığınızda GPU üzerinde CUDA programlamamda bir durum var, vectorbunun yerine "kullanmak zorunda" olduğunu düşündüğünüz insanları yanıtlamak unique_ptriçin bir işaretçi dizisi (ile cudaMalloc) gitmelisiniz . Ardından, bu verileri Ana Bilgisayar'da alırken, bir işaretçi için tekrar gitmelisiniz ve unique_ptrişaretçiyi kolayca işlemek iyi olur. Dönüştürme double*işleminin ekstra maliyeti vector<double>gereksizdir ve perf kaybına yol açar.


3

İzin vermek ve kullanmak için ek bir neden std::unique_ptr<T[]>, şu ana kadar yanıtlarda belirtilmemiş: dizi öğesi türünü iletmenizi sağlar.

Bu, #includebaşlıklardaki zincirleme ifadeleri en aza indirmek istediğinizde (oluşturma performansını optimize etmek için) kullanışlıdır .

Örneğin -

MyClass.h:

class ALargeAndComplicatedClassWithLotsOfDependencies;

class MyClass {
   ...
private:
   std::unique_ptr<ALargeAndComplicatedClassWithLotsOfDependencies[]> m_InternalArray;
};

MyClass.cpp:

#include "myclass.h"
#include "ALargeAndComplicatedClassWithLotsOfDependencies.h"

// MyClass implementation goes here

Yukarıdaki kod yapısıyla, herkesin gerektirdiği dahili uygulama bağımlılıklarını eklemek zorunda kalmadan #include "myclass.h"kullanabilir ve kullanabilir .MyClassMyClass::m_InternalArray

Eğer m_InternalArrayyerine olarak ilan edilmiştir std::array<ALargeAndComplicatedClassWithLotsOfDependencies>, ya da std::vector<...>sırasıyla - sonuç derleme zamanı hatası eksik bir tip, kullanımını teşebbüs olacaktır.


Bu özel kullanım durumunda, Pimpl deseninin bağımlılığı kırmasını tercih ederim - eğer sadece özel olarak kullanılırsa, sınıf yöntemleri uygulanana kadar tanım ertelenebilir; eğer herkesin kullanımına açıksa, o zaman sınıf kullanıcıları hakkında somut bilgiye sahip olmalılardı class ALargeAndComplicatedClassWithLotsOfDependencies. Yani mantıklı olarak bu tür senaryolarla karşılaşmamalısınız.

3

Kabul edilen cevabın ruhuna yeterince katılmıyorum. "Son çare aracı" mı? Ne münasebet!

Gördüğüm gibi, C ++ 'nın C ve diğer benzer dillere kıyasla en güçlü özelliklerinden biri, derlemeleri zamanında kontrol edebilmeleri ve yanlışlıkla kötüye kullanımı önleyebilmeleri için kısıtlamaları ifade edebilme yeteneğidir. Bu yüzden bir yapı tasarlarken kendinize hangi işlemlere izin vermesi gerektiğini sorun. Diğer tüm kullanımlar yasaklanmalıdır ve bu tür kısıtlamaların statik olarak (derleme zamanında) uygulanabilmesi en iyisidir, böylece yanlış kullanım bir derleme hatasına neden olur.

Yani bir diziye ihtiyaç duyulduğunda, aşağıdaki soruların cevapları davranışını belirtir: 1. a) çalışma zamanında dinamik mi, yoksa b) statik mi, ancak yalnızca çalışma zamanında mı biliniyor, yoksa c) statik mi ve derleme zamanında mı biliniyor? 2. Dizi yığına ayrılabilir mi, atanamaz mı?

Ve cevaplara dayanarak, böyle bir dizi için en iyi veri yapısı olarak gördüğüm budur:

       Dynamic     |   Runtime static   |         Static
Stack std::vector      unique_ptr<T[]>          std::array
Heap  std::vector      unique_ptr<T[]>     unique_ptr<std::array>

Evet, bence unique_ptr<std::array>de düşünülmeli ve ikisi de son çare değil. Sadece algoritmanıza en uygun olanı düşünün.

Bunların tümü, ham işaretçi-veri dizisi ( vector.data()/ array.data()/ uniquePtr.get()) aracılığıyla düz C API'leri ile uyumludur .

PS Yukarıdaki hususların yanı sıra, sahipliklerden biri de vardır: std::arrayve std::vectordeğer semantiğine sahip olmak (değere göre kopyalama ve değere geçmek için yerel desteğe sahip olmak), ancak unique_ptr<T[]>yalnızca hareket ettirilebilir (tek mülkiyeti zorlar). Her ikisi de farklı senaryolarda yararlı olabilir. Aksine, düz statik diziler ( int[N]) ve düz dinamik diziler ( new int[10]) hiçbiri sunmaz ve bu nedenle mümkünse kaçınılmalıdır - bu, vakaların büyük çoğunluğunda mümkün olmalıdır. Bu yeterli değilse, düz dinamik diziler de boyutlarını sorgulamanın bir yolunu sunmaz - bellek bozulmaları ve güvenlik delikleri için ekstra fırsat.


2

Bunlar, kapağın diğer tarafında "yakalandıktan" sonra belirli bir ömür ölçüsü olan mevcut bir API (pencere iletisi veya diş açmayla ilgili geri arama parametrelerini) üzerinden tek bir işaretçiyi işaretlediğinizde mümkün olan en doğru yanıt olabilir, ancak arama koduyla ilgisi yoktur:

unique_ptr<byte[]> data = get_some_data();

threadpool->post_work([](void* param) { do_a_thing(unique_ptr<byte[]>((byte*)param)); },
                      data.release());

Hepimiz işlerin bizim için iyi olmasını istiyoruz. C ++ diğer zamanlar içindir.


2

unique_ptr<char[]>C'nin performansını ve C ++ rahatlığını istediğiniz yerde kullanılabilir. Milyonlarda (tamam, henüz güvenmiyorsanız milyarlar) çalışmanız gerektiğini düşünün. Her birini ayrı bir nesnede stringveya vector<char>nesnede saklamak , bellek (yığın) yönetim yordamları için bir felaket olacaktır. Özellikle farklı dizeleri birçok kez ayırmanız ve silmeniz gerekiyorsa.

Ancak, birçok dizeyi saklamak için tek bir arabellek ayırabilirsiniz. Sen değil gibi olur char* buffer = (char*)malloc(total_size);(açık değil ise "neden akıllı ptrs kullanmak" için arama) açık nedenlerden dolayı. İsterdinunique_ptr<char[]> buffer(new char[total_size]);

Benzer şekilde, aynı performans ve rahatlık hususları charveri olmayanlar için de geçerlidir (milyonlarca vektör / matris / nesne düşünün).


Bunların hepsi büyük bir şey değil vector<char>mi? Sanırım cevap, tamponu oluşturduğunuzda sıfır-başlatılmaları olacaktır, oysa kullanmazlarsa olmayacaklardır unique_ptr<char[]>. Ama bu anahtar külçe cevabınızda eksik.
Arthur Tacca

2
  • İkili uyumluluk nedeniyle yalnızca bir işaretçi içerecek şekilde yapınıza ihtiyacınız vardır.
  • Ayrılan belleği döndüren bir API ile arayüz oluşturmalısınız new[]
  • Firmanızın veya projenizin kullanmaya karşı genel bir kuralı var std::vector örneğin dikkatsiz programcıların yanlışlıkla kopya koymasını önlemek için kullanımına
  • Dikkatsiz programcıların bu durumda yanlışlıkla kopyalarını girmesini engellemek istiyorsunuz.

C ++ kaplarının işaretçilerle kendi başınıza yuvarlanmaya tercih edilmesinin genel bir kuralı vardır. Genel bir kuraldır; istisnaları vardır. Fazlası var; bunlar sadece örnektir.


0

Kopyala oluşturulamayan dinamik bir nesne dizisine ihtiyacınız varsa, bir diziye akıllı bir işaretçi gitmenin yoludur. Örneğin, bir atom dizisine ihtiyacınız varsa.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.