Latar Belakang
Dalam C , RAII (Pemerolehan Sumber Adalah Permulaan) ialah digunakan untuk memastikan pembersihan sumber automatik. Apabila objek di luar skop, pemusnahnya dipanggil, melepaskan sebarang sumber yang dipegangnya.
Masalah
Pertimbangkan kelas C dengan objek OpenGL yang diurus melalui RAII:
class BufferObject { public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } };
Apabila digunakan dalam senario tertentu, seperti menyimpan dalam vektor atau kembali dari fungsi, masalah timbul dengan ralat OpenGL.
Analisis
Isu ini berpunca daripada kekurangan semantik salinan/pindah yang betul. Apabila menyalin objek (cth., push_back), hanya pembolehubah ahli disalin, meninggalkan kedua-dua objek dengan objek penimbal OpenGL yang sama. Selepas pemusnahan, objek pertama memadam penimbal, menjadikan objek kedua tidak sah.
Penyelesaian: Melaksanakan Move Semantics
Untuk menyelesaikan masalah ini, kelas hendaklah ditukar kepada a jenis bergerak sahaja, mengalih keluar pembina salinan dan pengendali tugasan salinan. Sebaliknya, alihkan pembina dan alihkan pengendali tugasan hendaklah diberikan bahawa pemindahan pemilikan sumber:
class BufferObject { public: BufferObject(const BufferObject &) = delete; BufferObject &operator=(const BufferObject &) = delete; BufferObject(BufferObject &&other) : buff_(other.buff_) { other.buff_ = 0; } BufferObject &operator=(BufferObject &&other) { if (this != &other) { Release(); buff_ = other.buff_; other.buff_ = 0; } return *this; } };
Ini memastikan bahawa hanya satu objek memiliki penimbal OpenGL pada bila-bila masa.
Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Ralat OpenGL Apabila Menggunakan RAII dalam C?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!