C에서 OpenGL 개체를 사용하는 RAII: 숨겨진 문제 이해
C 개체 지향 프로그래밍에서 리소스 획득은 초기화(RAII)입니다. 자원을 효율적으로 관리하는 데 사용되는 기술입니다. C 클래스 내에서 OpenGL 객체를 사용할 때 클래스가 소멸될 때 OpenGL 객체가 올바르게 해제되도록 RAII를 사용하는 것이 일반적입니다.
다음 코드 조각을 고려하세요.
class BufferObject { private: GLuint buff_; public: BufferObject() { glGenBuffers(1, &buff_); } ~BufferObject() { glDeleteBuffers(1, &buff_); } };
이 클래스는 OpenGL 객체에 대해 RAII를 올바르게 구현하는 것 같습니다. 그러나 클래스를 복사하거나 이동할 때 다음 코드와 같이 문제가 발생합니다.
vector<BufferObject> bufVec; { BufferObject some_buffer; //Initialize some_buffer; bufVec.push_back(some_buffer); } bufVec.back(); //buffer doesn't work. BufferObject InitBuffer() { BufferObject buff; //Do stuff with `buff` return buff; } auto buff = InitBuffer(); //Returned buffer doesn't work.
이러한 시나리오에서는 OpenGL 개체를 사용할 수 없게 되어 오류가 발생합니다.
이유 이 동작은 컴파일러에서 생성된 기본 복사 생성자와 할당 연산자에 있습니다. 이러한 작업은 단순히 객체의 멤버를 복사하므로 동일한 기본 OpenGL 객체를 참조하는 여러 C 객체가 생성됩니다. 원본 C 객체가 소멸되면 OpenGL 객체가 해제되어 다른 객체가 파괴된 리소스를 참조하게 됩니다.
이 문제를 해결하려면 BufferObject 클래스가 이동 전용 유형이어야 합니다. 이는 복사 생성자와 할당 연산자를 제거하고 OpenGL 개체의 소유권을 새 개체로 이전하는 이동 등가물을 제공하는 것을 의미합니다.
class BufferObject { private: GLuint buff_; public: BufferObject() { glGenBuffers(1, &buff_); } BufferObject(const BufferObject &) = delete; BufferObject &operator=(const BufferObject &) = delete; BufferObject(BufferObject &&other) : buff_(other.buff_) { other.buff_ = 0; } BufferObject &operator=(BufferObject &&other) { //ALWAYS check for self-assignment if(this != &other) { Release(); buff_ = other.buff_; other.buff_ = 0; } return *this; } ~BufferObject() {Release();} void Release(); { if(buff_) glDeleteBuffers(1, &buff_); } //Other members. };
이러한 변경을 통해 클래스는 OpenGL 개체가 올바르게 관리되고 클래스를 복사하거나 이동하는 경우에도 공개됩니다.
위 내용은 C에서 OpenGL 개체를 사용하는 RAII로 인해 개체를 복사하거나 이동할 때 어떻게 예기치 않은 동작이 발생할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!