Apakah ada kegunaan untuk unique_ptr dengan array?

238

std::unique_ptr memiliki dukungan untuk array, misalnya:

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

tetapi apakah itu dibutuhkan? mungkin lebih nyaman digunakan std::vectoratau std::array.

Apakah Anda menemukan kegunaan untuk konstruksi itu?

rawa
sumber
6
Untuk kelengkapan, saya harus menunjukkan bahwa tidak ada std::shared_ptr<T[]>, tetapi harus ada, dan mungkin akan ada di C ++ 14 jika ada yang bisa repot menulis proposal. Sementara itu, selalu ada boost::shared_array.
Nama samaran
13
std::shared_ptr<T []> sekarang dalam c ++ 17.
陳 力
Anda dapat menemukan banyak cara untuk melakukan apa saja di komputer. Konstruk ini memang digunakan, terutama di jalur panas, karena ini menghapus biaya operasi wadah jika Anda tahu persis cara menargetkan array Anda. Selain itu, itu membuat array karakter tanpa keraguan penyimpanan yang berdekatan.
kevr

Jawaban:

256

Beberapa orang tidak memiliki kemewahan menggunakan std::vector, bahkan dengan pengalokasi. Beberapa orang membutuhkan array berukuran dinamis, begitu std::arrayjuga keluar. Dan beberapa orang mendapatkan array mereka dari kode lain yang diketahui mengembalikan array; dan kode itu tidak akan ditulis ulang untuk mengembalikan vectoratau sesuatu.

Dengan mengizinkan unique_ptr<T[]>, Anda melayani kebutuhan itu.

Singkatnya, Anda gunakan unique_ptr<T[]>saat Anda membutuhkannya . Ketika alternatif tidak akan bekerja untuk Anda. Ini alat pilihan terakhir.

Nicol Bolas
sumber
27
@NoSenseEtAl: Saya tidak yakin apa bagian dari "beberapa orang tidak diizinkan untuk melakukan itu" lolos dari Anda. Beberapa proyek memiliki persyaratan yang sangat spesifik, dan di antaranya mungkin "Anda tidak bisa menggunakan vector". Anda dapat berdebat apakah persyaratan tersebut masuk akal atau tidak, tetapi Anda tidak dapat menyangkal bahwa persyaratan itu ada .
Nicol Bolas
21
Tidak ada alasan di dunia mengapa seseorang tidak dapat menggunakan std::vectorjika mereka dapat menggunakannya std::unique_ptr.
Miles Rout
66
inilah alasan untuk tidak menggunakan vektor: sizeof (std :: vector <char>) == 24; sizeof (std :: unique_ptr <char []>) == 8
Arvid
13
@DanNissenbaum Proyek-proyek ini ada. Beberapa industri yang berada di bawah pengawasan ketat, seperti misalnya penerbangan atau pertahanan, perpustakaan standar terlarang karena sulit untuk memverifikasi dan membuktikan bahwa itu benar untuk apa pun badan pengatur yang menetapkan peraturan. Anda mungkin berpendapat bahwa perpustakaan standar telah diuji dengan baik dan saya akan setuju dengan Anda tetapi Anda dan saya tidak membuat aturan.
Emily L.
16
@DanNissenbaum Juga beberapa sistem waktu nyata yang keras tidak diperbolehkan menggunakan alokasi memori dinamis sama sekali karena penundaan yang disebabkan oleh panggilan sistem mungkin tidak dibatasi secara teoritis dan Anda tidak dapat membuktikan perilaku waktu-nyata dari program. Atau batasnya mungkin terlalu besar yang melanggar batas WCET Anda. Meskipun tidak berlaku di sini, karena mereka juga tidak akan menggunakan unique_ptrtetapi proyek-proyek semacam itu benar-benar ada.
Emily L.
124

Ada pengorbanan, dan Anda memilih solusi yang sesuai dengan yang Anda inginkan. Dari atas kepala saya:

Ukuran inisial

  • vectordan unique_ptr<T[]>memungkinkan ukurannya ditentukan pada saat run-time
  • array hanya memungkinkan ukuran ditentukan pada waktu kompilasi

Mengubah ukuran

  • arraydan unique_ptr<T[]>tidak mengizinkan pengubahan ukuran
  • vector tidak

Penyimpanan

  • vectordan unique_ptr<T[]>menyimpan data di luar objek (biasanya di heap)
  • array menyimpan data secara langsung di objek

Penyalinan

  • arraydan vectormemungkinkan penyalinan
  • unique_ptr<T[]> tidak mengizinkan penyalinan

Tukar / pindahkan

  • vectordan unique_ptr<T[]>punya O (1) waktu swapdan memindahkan operasi
  • arraymemiliki O (n) waktu swapdan memindahkan operasi, di mana n adalah jumlah elemen dalam array

Pointer / referensi / pembatalan iterator

  • array memastikan pointer, referensi dan iterator tidak akan pernah batal ketika objek hidup, bahkan di swap()
  • unique_ptr<T[]>tidak memiliki iterator; pointer dan referensi hanya dibatalkan pada swap()saat objek hidup. (Setelah bertukar, pointer menunjuk ke array yang Anda bertukar, jadi mereka masih "valid" dalam pengertian itu.)
  • vector dapat membatalkan pointer, referensi dan iterator pada realokasi apa pun (dan memberikan beberapa jaminan bahwa realokasi hanya dapat terjadi pada operasi tertentu).

Kompatibilitas dengan konsep dan algoritma

  • arraydan vectorkeduanya adalah Wadah
  • unique_ptr<T[]> bukan sebuah Kontainer

Harus saya akui, ini sepertinya peluang untuk refactoring dengan desain berbasis kebijakan.

Nama samaran
sumber
1
Saya tidak yakin saya mengerti apa yang Anda maksud dalam konteks pembatalan pointer . Apakah ini tentang pointer ke objek itu sendiri, atau pointer ke elemen? Atau sesuatu yang lain? Apa jenis jaminan yang Anda dapatkan dari array yang tidak Anda dapatkan dari vektor?
jogojapan
3
Misalkan Anda memiliki iterator, pointer, atau referensi ke elemen a vector. Kemudian Anda meningkatkan ukuran atau kapasitas vectorsehingga memaksa realokasi. Kemudian iterator, pointer atau referensi tidak lagi menunjuk ke elemen vector. Inilah yang kami maksud dengan "invalidation". Masalah ini tidak terjadi array, karena tidak ada "realokasi". Sebenarnya, saya hanya memperhatikan detail dengan itu, dan saya sudah mengeditnya sesuai.
Nama samaran
1
Oke, tidak boleh ada pembatalan sebagai akibat dari realokasi dalam array atau unique_ptr<T[]>karena tidak ada realokasi. Tapi tentu saja, ketika array keluar dari cakupan, pointer ke elemen tertentu masih akan batal.
jogojapan
Ya, semua taruhan dibatalkan jika objek tidak lagi hidup.
Nama samaran
1
@rubenvb Tentu Anda bisa, tetapi Anda tidak bisa (misalnya) menggunakan rentang berbasis untuk loop langsung. Kebetulan, tidak seperti normal T[], ukuran (atau informasi yang setara) harus berkeliaran di suatu tempat untuk operator delete[]menghancurkan elemen array dengan benar. Akan lebih baik jika programmer memiliki akses ke sana.
Nama samaran
73

Salah satu alasan Anda mungkin menggunakan a unique_ptradalah jika Anda tidak ingin membayar biaya runtime dari inisialisasi nilai array.

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

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

The std::vectorkonstruktor dan std::vector::resize()akan menghargai-initialize T- tetapi newtidak akan melakukan itu jika Tadalah POD.

Lihat Nilai-Inisialisasi Objek di C ++ 11 dan std :: vector constructor

Perhatikan bahwa vector::reserveini bukan alternatif di sini: Apakah mengakses pointer mentah setelah std :: vector :: cadangan aman?

Itu alasan yang sama yang mungkin dipilih oleh programmer C malloc lebih calloc.

Charles Salvia
sumber
Namun alasan ini bukan satu-satunya solusi .
Ruslan
@Ruslan Dalam solusi tertaut elemen-elemen array dinamis masih diinisialisasi-nilai, tetapi inisialisasi nilai tidak melakukan apa-apa. Saya setuju bahwa pengoptimal yang gagal untuk menyadari bahwa tidak melakukan apa-apa 1000000 kali dapat diimplementasikan oleh kode tidak bernilai sepeser pun, tetapi orang mungkin lebih suka untuk tidak bergantung pada optimasi ini sama sekali.
Marc van Leeuwen
Kemungkinan lain adalah untuk memberikan kepada std::vectorsebuah pengalokasi kustom yang menghindari pembangunan jenis yang std::is_trivially_default_constructibledan penghancuran benda-benda yang std::is_trivially_destructible, meskipun ketat ini melanggar standar C ++ (karena jenis tersebut tidak default dijalankan).
Walter
Juga std::unique_ptrtidak menyediakan pengecekan terikat yang bertentangan dengan banyak std::vectorimplementasi.
diapir
@diapir Ini bukan tentang implementasinya: std::vectordiperlukan oleh Standar untuk memeriksa batasan dalam .at(). Saya kira Anda maksudkan bahwa beberapa implementasi memiliki mode debug yang akan memeriksa .operator[]juga, tapi saya menganggap itu tidak berguna untuk menulis kode portabel yang baik.
underscore_d
30

Sebuah std::vectordapat disalin sekitar, sambil unique_ptr<int[]>memungkinkan mengekspresikan kepemilikan unik dari array. std::array, di sisi lain, membutuhkan ukuran yang harus ditentukan pada waktu kompilasi, yang mungkin tidak mungkin dalam beberapa situasi.

Andy Prowl
sumber
2
Hanya karena sesuatu dapat disalin, tidak berarti harus demikian.
Nicol Bolas
4
@NicolBolas: Saya tidak mengerti. Salah satu mungkin ingin mencegah hal itu untuk alasan yang sama mengapa orang akan menggunakan unique_ptrbukan shared_ptr. Apakah saya melewatkan sesuatu?
Andy Prowl
4
unique_ptrtidak lebih dari sekadar mencegah penyalahgunaan yang tidak disengaja. Ini juga lebih kecil dan overhead yang lebih rendah daripada shared_ptr. Intinya adalah, walaupun senang memiliki semantik di kelas yang mencegah "penyalahgunaan", itu bukan satu-satunya alasan untuk menggunakan jenis tertentu. Dan vectorjauh lebih berguna sebagai penyimpanan array daripada unique_ptr<T[]>, jika tanpa alasan selain fakta bahwa ia memiliki ukuran .
Nicol Bolas
3
Saya pikir saya telah menjelaskan maksudnya: ada alasan lain untuk menggunakan jenis tertentu dari itu. Sama seperti ada alasan untuk lebih memilih vectordi unique_ptr<T[]>mana mungkin, alih-alih hanya mengatakan, "Anda tidak dapat menyalinnya" dan karena itu pilih unique_ptr<T[]>ketika Anda tidak ingin salinan. Menghentikan seseorang dari melakukan hal yang salah belum tentu merupakan alasan paling penting untuk memilih kelas.
Nicol Bolas
8
std::vectormemiliki lebih banyak overhead daripada std::unique_ptr- ia menggunakan ~ 3 pointer bukannya ~ 1. std::unique_ptrmemblokir penyalinan tetapi memungkinkan pemindahan konstruksi, yang jika secara semantik data yang Anda kerjakan hanya dapat dipindahkan tetapi tidak disalin, menginfeksi yang classberisi data tersebut. Memiliki operasi pada data yang tidak valid sebenarnya membuat kelas kontainer Anda lebih buruk, dan "jangan gunakan itu" tidak menghapus semua dosa. Harus meletakkan setiap instance dari Anda std::vectorke dalam kelas di mana Anda menonaktifkan secara manual moveadalah sakit kepala. std::unique_ptr<std::array>memiliki a size.
Yakk - Adam Nevraumont
22

Scott Meyers mengatakan ini dalam C ++ Modern yang Efektif

Keberadaan std::unique_ptruntuk array harus hanya menarik intelektual untuk Anda, karena std::array, std::vector, std::stringhampir selalu pilihan struktur data yang lebih baik dari array mentah. Tentang satu-satunya situasi yang bisa saya bayangkan ketika std::unique_ptr<T[]>masuk akal adalah ketika Anda menggunakan API seperti-C yang mengembalikan pointer mentah ke tumpukan tumpukan yang Anda anggap kepemilikan.

Saya pikir jawaban Charles Salvia relevan: itu std::unique_ptr<T[]>adalah satu-satunya cara untuk menginisialisasi array kosong yang ukurannya tidak diketahui pada waktu kompilasi. Apa yang akan dikatakan Scott Meyers tentang motivasi untuk menggunakan ini std::unique_ptr<T[]>?

newling
sumber
4
Sepertinya dia tidak membayangkan beberapa kasus penggunaan, yaitu buffer yang ukurannya tetap tetapi tidak diketahui pada waktu kompilasi, dan / atau buffer yang kami tidak memperbolehkan salinannya. Ada juga efisiensi sebagai alasan yang memungkinkan untuk memilihnya daripada vector stackoverflow.com/a/24852984/2436175 .
Antonio
17

Berlawanan dengan std::vectordan std::array, std::unique_ptrdapat memiliki pointer NULL.
Ini berguna saat bekerja dengan API C yang mengharapkan array atau NULL:

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());
}
George
sumber
10

Saya telah terbiasa unique_ptr<char[]>mengimplementasikan kumpulan memori yang telah dialokasikan sebelumnya yang digunakan dalam mesin game. Idenya adalah untuk menyediakan kumpulan memori yang telah dialokasikan sebelumnya yang digunakan alih-alih alokasi dinamis untuk mengembalikan hasil permintaan tabrakan dan hal-hal lain seperti fisika partikel tanpa harus mengalokasikan / membebaskan memori pada setiap frame. Ini cukup nyaman untuk skenario semacam ini di mana Anda memerlukan kumpulan memori untuk mengalokasikan objek dengan waktu hidup terbatas (biasanya satu, 2 atau 3 frame) yang tidak memerlukan logika penghancuran (hanya alokasi memori).

Simon Ferquel
sumber
9

Pola umum dapat ditemukan di beberapa panggilan Windows Win32 API , di mana penggunaan std::unique_ptr<T[]>bisa berguna, misalnya ketika Anda tidak tahu persis seberapa besar buffer output seharusnya ketika memanggil beberapa Win32 API (yang akan menulis beberapa data di dalam buffer itu):

// 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...
...
Mr.C64
sumber
Anda bisa menggunakannya std::vector<char>dalam kasus ini.
Arthur Tacca
@ArthurTacca - ... jika Anda tidak keberatan kompilator menginisialisasi setiap karakter dalam buffer Anda ke 0 satu-per-satu.
TED
9

Saya menghadapi kasus di mana saya harus menggunakan std::unique_ptr<bool[]>, yang ada di perpustakaan HDF5 (perpustakaan untuk penyimpanan data biner yang efisien, banyak digunakan dalam sains). Beberapa kompiler (Visual Studio 2015 dalam kasus saya) memberikan kompresistd::vector<bool> (dengan menggunakan 8 bools di setiap byte), yang merupakan bencana untuk sesuatu seperti HDF5, yang tidak peduli dengan kompresi itu. Denganstd::vector<bool> , HDF5 akhirnya membaca sampah karena kompresi itu.

Tebak siapa yang ada di sana untuk penyelamatan, dalam kasus di mana std::vectortidak bekerja, dan saya perlu mengalokasikan array dinamis dengan bersih? :-)

Fisikawan Kuantum
sumber
9

Singkatnya: sejauh ini yang paling hemat memori.

A std::stringdilengkapi dengan pointer, panjang, dan buffer "optimasi string pendek". Tetapi situasi saya adalah saya perlu menyimpan string yang hampir selalu kosong, dalam struktur yang saya miliki ratusan ribu. Dalam C, saya hanya akan menggunakan char *, dan itu akan menjadi null sebagian besar waktu. Yang bekerja untuk C ++ juga, kecuali bahwa char *tidak memiliki destruktor, dan tidak tahu untuk menghapus sendiri. Sebaliknya, a std::unique_ptr<char[]>akan menghapus sendiri ketika keluar dari ruang lingkup. Yang kosong std::stringmembutuhkan 32 byte, tetapi yang kosong std::unique_ptr<char[]>membutuhkan 8 byte, yaitu, persis ukuran penunjuknya.

Kelemahan terbesar adalah, setiap kali saya ingin mengetahui panjang tali, saya harus memanggilnya strlen.

jorgbrown
sumber
3

Untuk menjawab orang-orang yang berpikir Anda "harus" menggunakan, vectorbukan unique_ptrsaya memiliki kasus dalam pemrograman CUDA pada GPU ketika Anda mengalokasikan memori di Perangkat Anda harus menggunakan array pointer (dengan cudaMalloc). Kemudian, ketika mengambil data ini di Host, Anda harus menggunakan pointer lagi dan unique_ptrdapat menangani pointer dengan mudah. Biaya tambahan konversi double*ke vector<double>tidak perlu dan menyebabkan hilangnya kinerja.

Romain Laneuville
sumber
3

Satu alasan tambahan untuk membolehkan dan menggunakan std::unique_ptr<T[]>, yang belum disebutkan dalam tanggapan sejauh ini: memungkinkan Anda untuk meneruskan jenis elemen array.

Ini berguna ketika Anda ingin meminimalkan rantai #include pernyataan di header (untuk mengoptimalkan kinerja pembangunan.)

Misalnya -

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

Dengan struktur kode di atas, siapa pun dapat #include "myclass.h"dan menggunakan MyClass, tanpa harus menyertakan dependensi implementasi internal yang diperlukan oleh MyClass::m_InternalArray.

Jika m_InternalArraybukan dinyatakan sebagai std::array<ALargeAndComplicatedClassWithLotsOfDependencies>, atau std::vector<...>, masing-masing - hasilnya akan dicoba penggunaan jenis yang tidak lengkap, yang merupakan kesalahan waktu kompilasi.

Boris Shpungin
sumber
Untuk kasus penggunaan khusus ini, saya akan memilih pola Pimpl untuk menghentikan ketergantungan - jika hanya digunakan secara pribadi, maka definisi dapat ditangguhkan sampai metode kelas diimplementasikan; jika itu digunakan secara publik, maka pengguna kelas seharusnya sudah memiliki pengetahuan konkret tentang class ALargeAndComplicatedClassWithLotsOfDependencies. Jadi secara logis Anda seharusnya tidak mengalami skenario seperti itu.
3

Saya tidak bisa tidak setuju dengan semangat jawaban yang diterima dengan cukup kuat. "Alat pilihan terakhir"? Jauh dari itu!

Cara saya melihatnya, salah satu fitur terkuat dari C ++ dibandingkan dengan C dan beberapa bahasa lain yang serupa adalah kemampuan untuk mengekspresikan kendala sehingga mereka dapat diperiksa pada waktu kompilasi dan penyalahgunaan yang tidak disengaja dapat dicegah. Jadi, ketika merancang struktur, tanyakan pada diri sendiri operasi apa yang harus diizinkan. Semua penggunaan lain harus dilarang, dan yang terbaik adalah jika pembatasan tersebut dapat diimplementasikan secara statis (pada waktu kompilasi) sehingga penyalahgunaan menyebabkan kegagalan kompilasi.

Jadi ketika seseorang membutuhkan sebuah array, jawaban untuk pertanyaan berikut menentukan perilakunya: 1. Apakah ukurannya a) dinamis saat runtime, atau b) statis, tetapi hanya dikenal saat runtime, atau c) statis dan dikenal pada waktu kompilasi? 2. Dapatkah array dialokasikan pada stack atau tidak?

Dan berdasarkan jawaban, inilah yang saya lihat sebagai struktur data terbaik untuk array seperti itu:

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

Ya, saya pikir unique_ptr<std::array> juga harus dipertimbangkan, dan tidak ada alat terakhir. Coba pikirkan apa yang paling cocok dengan algoritma Anda.

Semua ini kompatibel dengan API C sederhana melalui pointer mentah ke array data ( vector.data()/ array.data()/ uniquePtr.get()).

PS Terlepas dari pertimbangan di atas, ada juga satu kepemilikan: std::arraydan std::vectormemiliki semantik nilai (memiliki dukungan asli untuk menyalin dan melewati nilai), sementara unique_ptr<T[]>hanya dapat dipindahkan (menegakkan kepemilikan tunggal). Entah dapat berguna dalam skenario yang berbeda. Sebaliknya, array statis polos ( int[N]) dan array dinamis polos ( new int[10]) tidak menawarkan dan karenanya harus dihindari jika mungkin - yang seharusnya dimungkinkan dalam sebagian besar kasus. Jika itu tidak cukup, array dinamis polos juga tidak menawarkan cara untuk menanyakan ukurannya - peluang tambahan untuk kerusakan memori dan celah keamanan.

Violet Giraffe
sumber
2

Mereka mungkin jawaban yang paling tepat ketika Anda hanya bisa menyodok satu pointer melalui API yang ada (pikirkan jendela pesan atau parameter panggilan balik terkait threading) yang memiliki ukuran seumur hidup setelah "tertangkap" di sisi lain dari palka, tetapi yang tidak terkait dengan kode panggilan:

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

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

Kita semua ingin semuanya menyenangkan bagi kita. C ++ untuk waktu lainnya.

Simon Buchan
sumber
2

unique_ptr<char[]>dapat digunakan di mana Anda ingin kinerja C dan kenyamanan C ++. Pertimbangkan Anda perlu beroperasi pada jutaan (ok, miliaran jika Anda belum percaya) dari string. Menyimpan masing-masing dalam objek stringatau terpisah vector<char>akan menjadi bencana bagi rutinitas manajemen memori (tumpukan). Terutama jika Anda perlu mengalokasikan dan menghapus string yang berbeda berkali-kali.

Namun, Anda dapat mengalokasikan buffer tunggal untuk menyimpan banyak string itu. Anda tidak akan suka char* buffer = (char*)malloc(total_size);karena alasan yang jelas (jika tidak jelas, cari "mengapa menggunakan smart ptrs"). Anda lebih sukaunique_ptr<char[]> buffer(new char[total_size]);

Secara analogi, pertimbangan kinerja & kenyamanan yang sama berlaku untuk non- chardata (pertimbangkan jutaan vektor / matriks / objek).

Serge Rogatch
sumber
Satu tidak menempatkan mereka semua dalam satu besar vector<char>? Jawabannya, saya kira, adalah karena mereka akan diinisialisasi nol ketika Anda membuat buffer, sedangkan mereka tidak akan menjadi jika Anda menggunakan unique_ptr<char[]>. Tapi nugget kunci ini hilang dari jawaban Anda.
Arthur Tacca
2
  • Anda perlu struktur Anda untuk memuat hanya pointer karena alasan kompatibilitas biner.
  • Anda perlu berinteraksi dengan API yang mengembalikan memori yang dialokasikan bersama new[]
  • Perusahaan atau proyek Anda memiliki aturan umum yang melarang penggunaan std::vector, misalnya, untuk mencegah programmer yang ceroboh memasukkan salinan secara tidak sengaja
  • Anda ingin mencegah programmer yang ceroboh memasukkan salinan secara tidak sengaja dalam hal ini.

Ada aturan umum bahwa wadah C ++ lebih disukai daripada bergulir sendiri dengan pointer. Ini adalah aturan umum; ini memiliki pengecualian. Masih ada lagi; ini hanya contoh.

Jimmy Hartzell
sumber
0

Jika Anda membutuhkan array dinamis dari objek yang tidak dapat dikopi-konstruksikan, maka pointer cerdas ke array adalah cara yang harus dilakukan. Misalnya, bagaimana jika Anda membutuhkan array atom.

Ilia Minkin
sumber