Kadang-kadang saya ingin mendelegasikan konstruksi objek yang dimiliki kelas ke fungsi terpisah. Sesuatu seperti
Vertex* new_vertex(const Options& options) {
// do stuff...
return new Vertex(...);
}
di mana fungsi ini hanya dimaksudkan untuk digunakan dalam kelas yang memiliki Vertex
. Jelas fungsi ini dapat menyebabkan kebingungan kehabisan memori, jadi saya ingin membuatnya sejelas mungkin. Apakah ada konvensi penamaan untuk fungsi-fungsi seperti itu?
c++
coding-standards
Shep
sumber
sumber
// TODO: Fix allocation of raw pointer.
unique_ptr
dengan memanggilrelease()
fungsinya, dan menggunakan pointer mentah seperti cara lama.// FIXME: Allocation of raw pointer
?new_vertex
jadi saya tahu objek baru dicetak. Anda bisa menyebutnyaCreate_new_vertex
lebih jelas. Adapun gagasan bahwa Anda tidak harus mengelola memori tumpukan tanpa petunjuk pintar, tidak pernah melihat kebenaran dalam hal itu - bahkan jika Anda tidak dapat mengelola memori tumpukan tanpa mereka, Anda juga tidak punya bisnis mengelola memori tumpukan dengan mereka!Jawaban:
Kembalikan
unique_ptr
:Hanya ada satu yang
unique_ptr
menunjuk ke objek tertentu (kecuali Anda menyalahgunakannya dengan melemparkan keVertex*
dan kembali, lagi pula). Anda tidak dapat menyalinunique_ptr
, hanya memindahkannya. Ketika aunique_ptr
dihancurkan (dan belum dipindahkan dari) itu bahkandelete
objek untuk Anda.make_unique
membuat yang baruVertex
dan membungkusnya dalamunique_ptr
; argumen yang Anda berikanmake_unique
adalah argumen yang diteruskan ke konstruktor.sumber
unique_ptr
lakukan itu. Jika itu harus menjadi nama karena alasan tertentu, maka saya rasa tidak, tapi mengapa itu harus nama?std::make_unique
? Itu verbose yang tidak perlu dan rawan kesalahan ...Tidak, tidak ada "cara standar" (tetapi ada kebijakan desain API yang saat ini dianggap sebagai "praktik terbaik").
Karena ambiguitas ini ("apa fungsi yang ingin saya lakukan oleh pointer mengembalikan?"), Saat ini dianggap praktik terbaik untuk memaksakan kebijakan masa pakai dan kepemilikan, melalui jenis pengembalian:
<vertex pointer type>
dapatstd::unique_ptr
("new_vertex tidak memiliki pointer"), ataustd::shared_ptr
("kode klien tidak memiliki pointer"), atau sesuatu yang lain, yang memiliki semantik kepemilikan yang jelas (misalnya,Vertex const * const
akan menunjukkan ke kode klien "baca alamat dan nilai, tetapi jangan ubah / jangan hapus pointer ").Secara umum, Anda tidak boleh mengembalikan pointer mentah (tetapi dalam beberapa kasus, "kepraktisan mengalahkan kemurnian").
TLDR : ada praktik terbaik ( ya ), tetapi bukan cara standar (dalam bahasa).
Edit :
Jika kelas memiliki Vertex, saya akan menulis seperti ini:
sumber
Ya, ada puluhan "standar" tentang ini
Rekomendasi jawaban
unique_ptr
mungkin adalah jawaban terbaik, tetapi jika Anda melihat petunjuk mentah, semua orang mengembangkan standar mereka sendiri.Secara umum fungsi bernama
create_____
ataunew______
ataualloc_____
cenderung menyiratkan objek baru.Namun
Pertimbangkan bahwa Anda mencampuradukkan perilaku. Anda sebenarnya tidak peduli apakah ini adalah contoh baru dari suatu objek atau tidak. Yang Anda pedulikan adalah apakah penelepon bertanggung jawab untuk menghancurkan objek atau tidak. Ada banyak API yang menyerahkan tanggung jawab untuk objek yang ada, dan fungsi-fungsi itu akan membutuhkan skema penamaan yang cocok. Mungkin
give______
.Jika Anda bersedia untuk menjauh dari C ++ ...
Jika Anda ingin menganggap Objective-C cukup mirip dengan C ++ untuk menjadi sumber jawaban, sebenarnya ada jawaban nyata dalam bahasa itu. Objective-C mengelola umur objek menggunakan jumlah referensi. Mereka membutuhkan cara untuk menggambarkan apakah Anda diberi tanggung jawab untuk suatu objek, atau hanya referensi ke objek yang ada. Jika Anda salah menjawab, Anda salah menghitung ulang dan kehilangan objek. Oleh karena itu mereka membuat aturan: setiap objek yang Anda kembalikan dimiliki oleh orang lain (jadi Anda harus menambah dan mengurangi sendiri penghitungan ref), kecuali untuk panggilan penciptaan yang melewati penunjuk yang sudah bertambah untuk Anda (Anda hanya perlu mengurangi). Panggilan-panggilan ini diidentifikasi oleh nama metode. Metode dimulai dengan
alloc
new
copy
ataumutableCopy
selalu mengembalikan objek baru. Jadi di sana, standar ditegakkan oleh bahasa.sumber