Saya tahu bahwa pertanyaan ini sudah ditanyakan beberapa kali tetapi saya tidak dapat menemukan jawaban untuk kasus khusus ini.
Katakanlah saya memiliki kelas sepele yang tidak memiliki sumber daya apa pun dan memiliki destruktor kosong dan konstruktor default. Ini memiliki beberapa variabel anggota dengan inisialisasi di dalam kelas; tidak satu pun dari mereka const
.
Saya ingin menginisialisasi ulang dan objek kelas tersebut tanpa menulis deInit
metode dengan tangan. Apakah aman melakukannya seperti ini?
void A::deInit()
{
new (this)A{};
}
Saya tidak dapat melihat masalah dengan itu - objek selalu dalam keadaan valid, this
masih menunjuk ke alamat yang sama; tapi ini C ++ jadi saya ingin memastikan.
c++
placement-new
Amomum
sumber
sumber
*this = A{};
?*this = A{};
berarti,this->operator=(A{});
yaitu membuat objek sementara dan menugaskannya*this
, mengganti nilai semua anggota data dengan nilai sementara. Karena itu yang Anda inginkan dan (menurut saya) lebih mudah dibaca daripada penempatan yang baru, saya akan menggunakannya.Jawaban:
Sama halnya dengan legalitas
delete this
, penempatan baruthis
juga diperbolehkan sejauh yang saya tahu. Juga, mengenai apakahthis
, atau petunjuk / referensi yang sudah ada sebelumnya dapat digunakan setelah itu, ada beberapa batasan:Dua yang pertama puas dalam contoh ini, tetapi dua yang terakhir perlu dipertimbangkan.
Mengenai poin ketiga, mengingat bahwa fungsinya non-const-kualifikasi, itu harus cukup aman untuk mengasumsikan bahwa objek aslinya adalah non-const. Kesalahan ada di sisi penelepon jika ketegaran telah dibuang. Mengenai const / anggota referensi, saya pikir itu dapat diperiksa dengan menyatakan bahwa ini dapat ditugaskan:
Tentu saja, karena penugasan adalah persyaratan, Anda bisa menggunakan
*this = {};
yang saya harapkan untuk menghasilkan program yang sama. Sebuah use case yang mungkin lebih menarik mungkin adalah menggunakan kembali memori*this
untuk objek tipe lain (yang akan gagal persyaratan untuk menggunakanthis
, setidaknya tanpa menafsirkan kembali + pencucian).Mirip dengan
delete this
, penempatan baruthis
hampir tidak dapat digambarkan sebagai "aman".sumber
delete ptr
adalahnew T()
. Kebalikannyanew(ptr)T{}
adalahptr->~T();
. stackoverflow.com/a/8918942/845092Aturan yang mencakup ini ada di [basic.life] / 5
dan [basic.life] / 8
Karena objek Anda sepele, Anda tidak perlu khawatir tentang [basic.life] / 5 dan selama Anda memenuhi poin-poin dari [basic.life] / 8, maka itu aman.
sumber